summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/gpu/adreno.txt3
-rw-r--r--Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt67
-rw-r--r--Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt16
-rw-r--r--Documentation/devicetree/bindings/media/video/msm-cpp.txt4
-rw-r--r--Documentation/devicetree/bindings/pci/msm_pcie.txt3
-rw-r--r--Documentation/devicetree/bindings/platform/msm/rmnet_ipa.txt2
-rw-r--r--Documentation/devicetree/bindings/platform/msm/rmnet_ipa3.txt2
-rw-r--r--Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt34
-rw-r--r--Documentation/devicetree/bindings/sound/qcom-audio-dev.txt257
-rw-r--r--Documentation/scheduler/sched-hmp.txt290
-rw-r--r--arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/apq8096-dragonboard.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/apq8096-sbc.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi76
-rw-r--r--arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-cmd.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-video.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-cmd.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-video.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msm-pm2falcon-rpm-regulator.dtsi238
-rw-r--r--arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi11
-rw-r--r--arch/arm/boot/dts/qcom/msm-pmfalcon-rpm-regulator.dtsi298
-rw-r--r--arch/arm/boot/dts/qcom/msm-pmi8994.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi19
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-cdp.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-dtp.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-fluid.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-gpu.dtsi34
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-liquid.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-mtp.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-camera-sensor-qrd-vr1.dtsi369
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-cdp.dtsi10
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi37
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon-cdp.dtsi16
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon-mtp.dtsi16
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon.dtsi45
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-interposer-pmfalcon.dtsi12
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi3
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi16
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dts1
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dtsi19
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-qrd-vr1.dtsi17
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-qrd.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi71
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-v2-interposer-msmfalcon.dtsi46
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-v2-qrd-skuk.dts2
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dts191
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dtsi65
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-v2.dtsi203
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-vidc.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt.dtsi427
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-blsp.dtsi340
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi336
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi767
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-rumi.dts13
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-sim.dts8
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon.dtsi96
-rw-r--r--arch/arm/boot/dts/qcom/msmtriton-regulator.dtsi168
-rw-r--r--arch/arm/boot/dts/qcom/msmtriton-rumi.dts5
-rw-r--r--arch/arm/boot/dts/qcom/msmtriton.dtsi58
-rw-r--r--arch/arm/configs/msmcortex_defconfig2
-rw-r--r--arch/arm/configs/msmfalcon_defconfig1
-rw-r--r--arch/arm/mm/dma-mapping.c3
-rw-r--r--arch/arm64/configs/msm-perf_defconfig1
-rw-r--r--arch/arm64/configs/msm_defconfig1
-rw-r--r--arch/arm64/configs/msmcortex-perf_defconfig3
-rw-r--r--arch/arm64/configs/msmcortex_defconfig3
-rw-r--r--arch/arm64/mm/dma-mapping.c1
-rw-r--r--drivers/char/diag/diagchar_core.c7
-rw-r--r--drivers/char/diag/diagfwd_glink.c3
-rw-r--r--drivers/char/diag/diagfwd_mhi.c6
-rw-r--r--drivers/char/diag/diagfwd_mhi.h3
-rw-r--r--drivers/char/diag/diagfwd_peripheral.c37
-rw-r--r--drivers/char/diag/diagfwd_peripheral.h1
-rw-r--r--drivers/clk/clk.c356
-rw-r--r--drivers/clk/clk.h4
-rw-r--r--drivers/clk/msm/clock-gpu-cobalt.c3
-rw-r--r--drivers/clk/msm/clock-mmss-cobalt.c81
-rw-r--r--drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c4
-rw-r--r--drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c18
-rw-r--r--drivers/clk/qcom/clk-alpha-pll.c463
-rw-r--r--drivers/clk/qcom/clk-alpha-pll.h24
-rw-r--r--drivers/clk/qcom/clk-branch.c59
-rw-r--r--drivers/clk/qcom/clk-pll.h9
-rw-r--r--drivers/clk/qcom/clk-rcg2.c56
-rw-r--r--drivers/clk/qcom/clk-regmap.h8
-rw-r--r--drivers/clk/qcom/gpucc-msmfalcon.c14
-rw-r--r--drivers/cpufreq/qcom-cpufreq.c32
-rw-r--r--drivers/crypto/msm/qce50.c21
-rw-r--r--drivers/devfreq/devfreq.c13
-rw-r--r--drivers/gpu/msm/a5xx_reg.h8
-rw-r--r--drivers/gpu/msm/adreno.c15
-rw-r--r--drivers/gpu/msm/adreno.h2
-rw-r--r--drivers/gpu/msm/adreno_a4xx_preempt.c2
-rw-r--r--drivers/gpu/msm/adreno_a5xx.c66
-rw-r--r--drivers/gpu/msm/adreno_a5xx.h1
-rw-r--r--drivers/gpu/msm/adreno_perfcounter.c32
-rw-r--r--drivers/gpu/msm/kgsl.c225
-rw-r--r--drivers/gpu/msm/kgsl.h3
-rw-r--r--drivers/gpu/msm/kgsl_debugfs.c93
-rw-r--r--drivers/gpu/msm/kgsl_iommu.c33
-rw-r--r--drivers/gpu/msm/kgsl_mmu.c27
-rw-r--r--drivers/gpu/msm/kgsl_mmu.h5
-rw-r--r--drivers/gpu/msm/kgsl_sharedmem.c40
-rw-r--r--drivers/gpu/msm/kgsl_sharedmem.h9
-rw-r--r--drivers/iio/adc/qcom-rradc.c19
-rw-r--r--drivers/iio/adc/qcom-tadc.c2
-rw-r--r--drivers/iommu/arm-smmu.c52
-rw-r--r--drivers/iommu/iommu-debug.c2
-rw-r--r--drivers/leds/leds-qpnp-flash-v2.c984
-rw-r--r--drivers/leds/leds-qpnp-flash.c3
-rw-r--r--drivers/leds/leds-qpnp-wled.c258
-rw-r--r--drivers/media/platform/msm/camera_v2/common/cam_soc_api.c2
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp40.c2
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c6
-rw-r--r--drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c4
-rw-r--r--drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c4
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c74
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c2
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_tz_i2c.c2
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_debug.c285
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_debug.h11
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c34
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c3
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h22
-rw-r--r--drivers/media/platform/msm/vidc/hfi_packetization.c27
-rw-r--r--drivers/media/platform/msm/vidc/msm_v4l2_vidc.c20
-rw-r--r--drivers/media/platform/msm/vidc/msm_venc.c42
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc.c4
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_debug.c2
-rw-r--r--drivers/media/platform/msm/vidc/venus_hfi.c18
-rw-r--r--drivers/media/platform/msm/vidc/venus_hfi.h3
-rw-r--r--drivers/media/platform/msm/vidc/vidc_hfi_api.h8
-rw-r--r--drivers/media/platform/msm/vidc/vidc_hfi_helper.h10
-rw-r--r--drivers/mfd/wcd9xxx-utils.c22
-rw-r--r--drivers/misc/hdcp.c59
-rw-r--r--drivers/misc/qseecom.c58
-rw-r--r--drivers/net/wireless/ath/wil6210/pmc.c55
-rw-r--r--drivers/nfc/nq-nci.c104
-rw-r--r--drivers/nfc/nq-nci.h9
-rw-r--r--drivers/pci/host/pci-msm.c37
-rw-r--r--drivers/phy/phy-qcom-ufs-qmp-v3.h12
-rw-r--r--drivers/pinctrl/qcom/pinctrl-msmfalcon.c256
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa.c6
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_dp.c18
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_i.h2
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c23
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_dp.c86
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_i.h2
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_uc.c8
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c25
-rw-r--r--drivers/platform/msm/msm_11ad/msm_11ad.c48
-rw-r--r--drivers/power/qcom-charger/fg-core.h40
-rw-r--r--drivers/power/qcom-charger/fg-memif.c193
-rw-r--r--drivers/power/qcom-charger/fg-reg.h25
-rw-r--r--drivers/power/qcom-charger/fg-util.c76
-rw-r--r--drivers/power/qcom-charger/qpnp-fg-gen3.c400
-rw-r--r--drivers/power/qcom-charger/qpnp-smb2.c36
-rw-r--r--drivers/power/qcom-charger/smb-lib.c308
-rw-r--r--drivers/power/qcom-charger/smb-lib.h15
-rw-r--r--drivers/power/qcom-charger/smb-reg.h4
-rw-r--r--drivers/power/qcom-charger/smb138x-charger.c4
-rw-r--r--drivers/regulator/qpnp-labibb-regulator.c341
-rw-r--r--drivers/scsi/ufs/ufs-qcom.c84
-rw-r--r--drivers/scsi/ufs/ufshcd.c178
-rw-r--r--drivers/scsi/ufs/ufshcd.h17
-rw-r--r--drivers/scsi/ufs/ufshci.h1
-rw-r--r--drivers/soc/qcom/glink.c1
-rw-r--r--drivers/soc/qcom/icnss.c46
-rw-r--r--drivers/soc/qcom/memshare/msm_memshare.c14
-rw-r--r--drivers/soc/qcom/msm_smem.c137
-rw-r--r--drivers/soc/qcom/secure_buffer.c2
-rw-r--r--drivers/soc/qcom/smem_debug.c9
-rw-r--r--drivers/soc/qcom/smem_private.h3
-rw-r--r--drivers/soc/qcom/sysmon.c6
-rw-r--r--drivers/soc/qcom/wlan_firmware_service_v01.c62
-rw-r--r--drivers/soc/qcom/wlan_firmware_service_v01.h22
-rw-r--r--drivers/spmi/spmi-pmic-arb.c51
-rw-r--r--drivers/thermal/msm_thermal.c16
-rw-r--r--drivers/usb/core/driver.c12
-rw-r--r--drivers/usb/core/hub.c11
-rw-r--r--drivers/usb/gadget/configfs.c9
-rw-r--r--drivers/usb/gadget/function/f_mtp.c14
-rw-r--r--drivers/usb/host/xhci-hub.c4
-rw-r--r--drivers/usb/host/xhci-plat.c8
-rw-r--r--drivers/usb/pd/policy_engine.c66
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c146
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.h5
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_aux.c14
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.c56
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.h11
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c6
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.h3
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_clk.c27
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_clk.h15
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_host.c6
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.c6
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c8
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c106
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_video.c8
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_layer.c14
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c47
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pipe.c5
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp.c14
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c2
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_trace.h16
-rw-r--r--drivers/video/fbdev/msm/mdss_util.c25
-rw-r--r--drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d.c9
-rw-r--r--drivers/video/fbdev/msm/msm_mdss_io_8974.c52
-rw-r--r--include/linux/clk-provider.h12
-rw-r--r--include/linux/filter.h6
-rw-r--r--include/linux/iommu.h1
-rw-r--r--include/linux/nfcinfo.h6
-rw-r--r--include/linux/qdsp6v2/apr_tal.h2
-rw-r--r--include/linux/sched/sysctl.h2
-rw-r--r--include/linux/spmi.h15
-rw-r--r--include/linux/usb.h9
-rw-r--r--include/net/tcp.h1
-rw-r--r--include/sound/apr_audio-v2.h53
-rw-r--r--include/sound/msm-dai-q6-v2.h11
-rw-r--r--include/sound/q6afe-v2.h16
-rw-r--r--include/trace/events/sched.h25
-rw-r--r--include/uapi/linux/Kbuild1
-rw-r--r--include/uapi/linux/nfc/Kbuild2
-rw-r--r--include/uapi/linux/nfc/nfcinfo.h21
-rw-r--r--include/uapi/linux/v4l2-controls.h9
-rw-r--r--include/uapi/media/msm_sde_rotator.h6
-rw-r--r--include/uapi/media/msmb_ispif.h3
-rw-r--r--kernel/Documentation/firmware_updater/request_firmware.txt22
-rw-r--r--kernel/Documentation/firmware_updater/synaptics_fw_updaterbin666266 -> 0 bytes
-rw-r--r--kernel/Documentation/firmware_updater/synaptics_fw_updater.c753
-rw-r--r--kernel/Documentation/firmware_updater/synaptics_fw_updater_readme.txt41
-rw-r--r--kernel/arch/arm/configs/omap3_beagle_android_defconfig2419
-rw-r--r--kernel/arch/arm/configs/panda_defconfig331
-rw-r--r--kernel/arch/arm/mach-omap2/board-omap3beagle.c1038
-rw-r--r--kernel/arch/arm/mach-omap2/board-omap4panda.c1053
-rw-r--r--kernel/drivers/input/touchscreen/Kconfig721
-rw-r--r--kernel/drivers/input/touchscreen/Makefile68
-rw-r--r--kernel/drivers/input/touchscreen/synaptics_fw_update.c1698
-rw-r--r--kernel/drivers/input/touchscreen/synaptics_i2c_rmi4.c2162
-rw-r--r--kernel/drivers/input/touchscreen/synaptics_i2c_rmi4.h286
-rw-r--r--kernel/drivers/input/touchscreen/synaptics_rmi_dev.c710
-rw-r--r--kernel/include/linux/input/synaptics_dsx.h59
-rw-r--r--kernel/sched/Makefile2
-rw-r--r--kernel/sched/boost.c226
-rw-r--r--kernel/sched/core.c11
-rw-r--r--kernel/sched/core_ctl.c39
-rw-r--r--kernel/sched/fair.c153
-rw-r--r--kernel/sched/hmp.c512
-rw-r--r--kernel/sched/rt.c12
-rw-r--r--kernel/sched/sched.h47
-rw-r--r--kernel/sched/tune.c184
-rw-r--r--kernel/sysctl.c19
-rw-r--r--kernel/time/hrtimer.c7
-rw-r--r--kernel/time/timer.c24
-rw-r--r--mm/debug-pagealloc.c1
-rw-r--r--net/core/filter.c9
-rw-r--r--net/ipv4/tcp_ipv4.c19
-rw-r--r--net/ipv6/tcp_ipv6.c6
-rw-r--r--net/netfilter/xt_IDLETIMER.c2
-rw-r--r--net/rmnet_data/rmnet_data_vnd.c1
-rw-r--r--net/rose/rose_in.c3
-rw-r--r--net/wireless/db.txt95
-rw-r--r--sound/soc/codecs/msm8x16/msm8x16-wcd.c109
-rw-r--r--sound/soc/codecs/msm8x16/msm8x16-wcd.h27
-rw-r--r--sound/soc/codecs/wcd-mbhc-v2.c5
-rw-r--r--sound/soc/codecs/wcd9335.c10
-rw-r--r--sound/soc/codecs/wcd934x/wcd934x.c28
-rw-r--r--sound/soc/codecs/wcd9xxx-resmgr-v2.c74
-rw-r--r--sound/soc/codecs/wcd9xxx-resmgr-v2.h2
-rw-r--r--sound/soc/msm/Kconfig76
-rw-r--r--sound/soc/msm/Makefile15
-rw-r--r--sound/soc/msm/msm-audio-pinctrl.h5
-rw-r--r--sound/soc/msm/msm-dai-fe.c32
-rw-r--r--sound/soc/msm/msmcobalt.c15
-rw-r--r--sound/soc/msm/msmfalcon-common.c2806
-rw-r--r--sound/soc/msm/msmfalcon-common.h103
-rw-r--r--sound/soc/msm/msmfalcon-ext-dai-links.c1967
-rw-r--r--sound/soc/msm/msmfalcon-external.c1765
-rw-r--r--sound/soc/msm/msmfalcon-external.h50
-rw-r--r--sound/soc/msm/msmfalcon-internal.c2970
-rw-r--r--sound/soc/msm/msmfalcon-internal.h32
-rw-r--r--sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c15
-rw-r--r--sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c229
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c188
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c135
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c458
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h35
-rw-r--r--sound/soc/msm/qdsp6v2/q6afe.c14
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c27
-rw-r--r--sound/soc/msm/qdsp6v2/q6audio-v2.c84
-rw-r--r--sound/soc/msm/qdsp6v2/q6voice.h2
-rw-r--r--sound/soc/soc-compress.c10
-rw-r--r--sound/soc/soc-pcm.c2
295 files changed, 21776 insertions, 14545 deletions
diff --git a/Documentation/devicetree/bindings/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt
index 44c874a7a080..8a79626125d9 100644
--- a/Documentation/devicetree/bindings/gpu/adreno.txt
+++ b/Documentation/devicetree/bindings/gpu/adreno.txt
@@ -154,6 +154,9 @@ GPU Quirks:
detection logic
- qcom,gpu-quirk-dp2clockgating-disable:
Disable RB sampler data path clock gating optimization
+- qcom,gpu-quirk-lmloadkill-disable:
+ Use register setting to disable local memory(LM) feature
+ to avoid corner case error
KGSL Memory Pools:
- qcom,gpu-mempools: Container for sets of GPU mempools.Multiple sets
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt b/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt
index 8365762e520f..4808d1dda5c1 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt
@@ -11,6 +11,8 @@ Main node:
Required properties:
- compatible : Should be "qcom,qpnp-flash-led-v2"
- reg : Base address and size for flash LED modules
+- qcom,pmic-revid : phandle of PMIC revid module. This is used to
+ identify the PMIC subtype.
Optional properties:
- interrupts : Specifies the interrupts associated with flash-led.
@@ -32,6 +34,18 @@ Optional properties:
- qcom,vph-droop-debounce-us : Integer property to specify VPH droop debounce time. It is only used
if qcom,vph-droop-det is specified. Valid values are 0, 8, 16 and 26.
Unit is uS.
+- qcom,led1n2-iclamp-low-ma : Integer property to specify current clamp low
+ level for mitigation. Unit is mA. Allowed
+ values are same as under qcom,max-current.
+- qcom,led1n2-iclamp-mid-ma : Integer property to specify current clamp mid
+ level for mitigation. Unit is mA. Allowed
+ values are same as under qcom,max-current.
+- qcom,led3-iclamp-low-ma : Integer property to specify current clamp low
+ level for mitigation. Unit is mA. Allowed
+ values are same as under qcom,max-current.
+- qcom,led3-iclamp-mid-ma : Integer property to specify current clamp mid
+ level for mitigation. Unit is mA. Allowed
+ values are same as under qcom,max-current.
- qcom,vled-max-uv : Integer property for flash current predictive mitigation.
Default value is 3500000 uV.
- qcom,ibatt-ocp-threshold-ua : Integer property for flash current predictive mitigation.
@@ -64,12 +78,47 @@ Optional properties:
- qcom,thermal-derate-current : Array of currrent limits for thermal mitigation. Required if
qcom,thermal-derate-en is specified. Unit is mA. Format is
qcom,thermal-derate-current = <OTST1_LIMIT, OTST2_LIMIT, OTST3_LIMIT>.
+- qcom,otst-ramp-back-up-dis : Boolean property to disable current ramp
+ backup after thermal derate trigger is
+ deasserted.
+- qcom,thermal-derate-slow : Integer property to specify slow ramping
+ down thermal rate. Unit is in uS. Allowed
+ values are: 128, 256, 512, 1024, 2048, 4096,
+ 8192 and 314592.
+- qcom,thermal-derate-fast : Integer property to specify fast ramping
+ down thermal rate. Unit is in uS. Allowed
+ values are: 32, 64, 96, 128, 256, 384 and
+ 512.
+- qcom,thermal-debounce : Integer property to specify thermal debounce
+ time. It is only used if qcom,thermal-derate-en
+ is specified. Unit is in uS. Allowed values
+ are: 0, 16, 32, 64.
+- qcom,thermal-hysteresis : Integer property to specify thermal derating
+ hysteresis. Unit is in deciDegC. It is only
+ used if qcom,thermal-derate-en is specified.
+ Allowed values are:
+ 0, 15, 30, 45 for pmicobalt.
+ 0, 20, 40, 60 for pm2falcon.
+- qcom,thermal-thrsh1 : Integer property to specify OTST1 threshold
+ for thermal mitigation. Unit is in Celsius.
+ Accepted values are:
+ 85, 79, 73, 67, 109, 103, 97, 91.
+- qcom,thermal-thrsh2 : Integer property to specify OTST2 threshold
+ for thermal mitigation. Unit is in Celsius.
+ Accepted values are:
+ 110, 104, 98, 92, 134, 128, 122, 116.
+- qcom,thermal-thrsh3 : Integer property to specify OTST3 threshold
+ for thermal mitigation. Unit is in Celsius.
+ Accepted values are:
+ 125, 119, 113, 107, 149, 143, 137, 131.
- qcom,hw-strobe-option : Integer type to specify hardware strobe option. Based on the specified
value, additional GPIO configuration may be required to provide strobing
support. Supported values are:
0: Flash strobe is used for LED1, LED2, LED3
1: Flash strobe is used for LED1, LED2 and GPIO10 is used for LED3
2: Flash strobe is used for LED1; GPIO9 is used for LED2; GPIO10 is used for LED3
+- switchX-supply : phandle of the regulator that needs to be used
+ as a supply for flash switch_X device.
Child node: Contains settings for each individual LED. Each LED channel needs a flash node and
torch node for itself, and an individual switch node to serve as an overall switch.
@@ -126,15 +175,6 @@ Optional properties:
be edge triggered. Otherwise, it is level triggered.
- qcom,hw-strobe-active-low : Boolean property to select strobe signal polarity. If defined, hw-strobe
signal polarity is set to active-low, else it is active-high.
-- reg<n> : reg<n> (<n> represents number. e.g. 0,1,2,..) subnode is to add support for
- multiple power sources. This subnode should only be specified for switch nodes.
- Required property inside regulator node:
- - regulator-name : Name of the regulator which has to be used for this
- switch node.
- Optional property inside regulator node:
- - max-voltage-uv : This specifies max voltage of regulator. Some switch
- or boost regulator does not need this property.
-
Example:
qcom,leds@d300 {
compatible = "qcom,qpnp-flash-led-v2";
@@ -160,6 +200,7 @@ Example:
qcom,hdrm-auto-mode;
qcom,isc-delay = <192>;
+ switch0-supply = <&pmicobalt_bob>;
pmi8998_flash0: qcom,flash_0 {
label = "flash";
@@ -254,10 +295,6 @@ Example:
qcom,led-mask = <3>;
qcom,default-led-trigger =
"switch0_trigger";
- reg0 {
- regulator-name = "pmicobalt_bob";
- max-voltage-uv = <3600000>;
- };
};
pmi8998_switch1: qcom,led_switch_1 {
@@ -266,10 +303,6 @@ Example:
qcom,led-mask = <4>;
qcom,default-led-trigger =
"switch1_trigger";
- reg0 {
- regulator-name = "pmicobalt_bob";
- max-voltage-uv = <3600000>;
- };
};
};
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt b/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt
index ebbcfe5b2fd0..4b23cb1e9a9c 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt
@@ -25,7 +25,11 @@ Optional properties for WLED:
- linux,default-trigger : trigger for the backlight. default is NONE.
- qcom,fdbk-output : string feedback current output for wled module. The accepted values
are "wled1", "wled2", "wled3", "wled4" and "auto". default is "auto".
-- qcom,vref-mv : maximum reference voltage in mv. default is 350.
+- qcom,vref-uv : maximum reference voltage in uV.
+ For pmi8994/8952/8996, supported values are from 300000 to 675000
+ with a step size of 25000, the default value is 350000.
+ For pmicobalt/pm2falcon, supported values are from 60000 to 397500
+ with a step size of 22500, the default value is 127500.
- qcom,switch-freq-khz : switch frequency in khz. default is 800.
- qcom,ovp-mv : Over voltage protection threshold in mV. Default is
29500. Supported values are:
@@ -64,9 +68,15 @@ Optional properties for WLED:
- qcom,cons-sync-write-delay-us : Specify in 'us' the duration of delay between two consecutive writes to
SYNC register.
- qcom,sc-deb-cycles : debounce time for short circuit detection
+- qcom,loop-ea-gm : control the gm for gm stage in control loop. default is 3.
+- qcom,loop-auto-gm-en : A boolean property to specify if auto gm is enabled.
+- qcom,loop-auto-gm-thresh : Specify auto gm threshold if "loop-auto-gm-en" is defined.
+ Supported values are: 0 - 3.
+- qcom,lcd-auto-pfm-thresh : Specify the auto-pfm threshold, if the headroom voltage level
+ falls below this threshold and auto PFM is enabled, boost
+ controller will enter into PFM mode automatically.
Optional properties if 'qcom,disp-type-amoled' is mentioned in DT:
-- qcom,loop-ea-gm : control the gm for gm stage in control loop. default is 3.
- qcom,loop-comp-res-kohm : control to select the compensation resistor in kohm. default is 320.
- qcom,vref-psm-mv : reference psm voltage in mv. default for amoled is 450.
- qcom,avdd-mode-spmi: Boolean property to enable AMOLED_VOUT programming via SPMI. If not specified,
@@ -94,7 +104,7 @@ Example:
linux,name = "wled";
linux,default-trigger = "bkl-trigger";
qcom,fdbk-output = "auto";
- qcom,vref-mv = <350>;
+ qcom,vref-uv = <350000>;
qcom,switch-freq-khz = <800>;
qcom,ovp-mv = <29500>;
qcom,ilim-ma = <980>;
diff --git a/Documentation/devicetree/bindings/media/video/msm-cpp.txt b/Documentation/devicetree/bindings/media/video/msm-cpp.txt
index 52abf409cb65..ade5fbe8cbd7 100644
--- a/Documentation/devicetree/bindings/media/video/msm-cpp.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-cpp.txt
@@ -26,6 +26,8 @@ Required properties:
and reset lines used by this controller.
- reset-names: reset signal name strings sorted in the same order as the resets
property.
+- qcom,src-clock-rates = This is an array which holds clock rates for cpp src
+ clocks. The maximum size for the array is 10.
Required properties of the child node:
- qcom,stripe-base = Base offset of stripes in cpp payload.
@@ -107,6 +109,8 @@ Example:
<0x24 0x10000000>,
<0x28 0x10000000>,
<0x2C 0x10000000>;
+ qcom,src-clock-rates = <100000000 200000000 384000000 404000000
+ 480000000 576000000 600000000>;
qcom,cpp-fw-payload-info {
qcom,stripe-base = <553>;
qcom,plane-base = <481>;
diff --git a/Documentation/devicetree/bindings/pci/msm_pcie.txt b/Documentation/devicetree/bindings/pci/msm_pcie.txt
index 21b6d99424c0..a50e0c2b2c35 100644
--- a/Documentation/devicetree/bindings/pci/msm_pcie.txt
+++ b/Documentation/devicetree/bindings/pci/msm_pcie.txt
@@ -93,6 +93,8 @@ Optional Properties:
and assign for each endpoint.
- qcom,ep-latency: The time (unit: ms) to wait for the PCIe endpoint to become
stable after power on, before de-assert the PERST to the endpoint.
+ - qcom,wr-halt-size: With base 2, this exponent determines the size of the
+ data that PCIe core will halt on for each write transaction.
- qcom,cpl-timeout: Completion timeout value. This value specifies the time range
which the root complex will send out a completion packet if there is no response
from the endpoint.
@@ -270,6 +272,7 @@ Example:
qcom,smmu-exist;
qcom,smmu-sid-base = <0x1480>;
qcom,ep-latency = <100>;
+ qcom,wr-halt-size = <0xa>; /* 1KB */
qcom,cpl-timeout = <0x2>;
iommus = <&anoc0_smmu>;
diff --git a/Documentation/devicetree/bindings/platform/msm/rmnet_ipa.txt b/Documentation/devicetree/bindings/platform/msm/rmnet_ipa.txt
index 102b304f5fb3..d8934c01cc71 100644
--- a/Documentation/devicetree/bindings/platform/msm/rmnet_ipa.txt
+++ b/Documentation/devicetree/bindings/platform/msm/rmnet_ipa.txt
@@ -12,9 +12,11 @@ Optional:
regarding scatter-gather capability
- qcom,ipa-napi-enable: Boolean context flag to indicate whether
to enable napi framework or not
+- qcom,wan-rx-desc-size: size of WAN rx desc fifo ring, default is 256
Example:
qcom,rmnet-ipa {
compatible = "qcom,rmnet-ipa";
+ qcom,wan-rx-desc-size = <256>;
}
diff --git a/Documentation/devicetree/bindings/platform/msm/rmnet_ipa3.txt b/Documentation/devicetree/bindings/platform/msm/rmnet_ipa3.txt
index 7ee28664668b..e9575f150c5e 100644
--- a/Documentation/devicetree/bindings/platform/msm/rmnet_ipa3.txt
+++ b/Documentation/devicetree/bindings/platform/msm/rmnet_ipa3.txt
@@ -12,9 +12,11 @@ Optional:
regarding scatter-gather capability
- qcom,ipa-napi-enable: Boolean context flag to indicate whether
to enable napi framework or not
+- qcom,wan-rx-desc-size: size of WAN rx desc fifo ring, default is 256
Example:
qcom,rmnet-ipa3 {
compatible = "qcom,rmnet-ipa3";
+ qcom,wan-rx-desc-size = <256>;
}
diff --git a/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt b/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt
index 7be400da0d62..0545f6b7b59a 100644
--- a/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt
@@ -8,7 +8,7 @@ display panels, LCD or AMOLED.
Main node required properties:
- compatible: Must be "qcom,qpnp-labibb-regulator"
-- qpnp,qpnp-labibb-mode: A string used to specify the working mode of LAB/IBB
+- qcom,qpnp-labibb-mode: A string used to specify the working mode of LAB/IBB
regulators when bootloader does not turned on the
display panel. Could be "lcd" or "amoled".
"lcd" means using LAB and IBB regulators are
@@ -26,9 +26,9 @@ Main node optional properties:
in LAB and IBB modules. Make sure the
hardware has needed support before
enabling this property.
-- qpnp,swire-control: A bool property which indicates if the LAB/IBB is
+- qcom,swire-control: A bool property which indicates if the LAB/IBB is
controlled by the SWIRE interface. Enable only
- if qpnp,qpnp-labibb-mode = "amoled".
+ if qcom,qpnp-labibb-mode = "amoled".
- qcom,labibb-ttw-force-lab-on: A boolean property which forces LAB to be
always on during TTW mode.
- qcom,skip-2nd-swire-cmd: A boolean property which indicates if
@@ -82,8 +82,10 @@ LAB subnode required properties:
are 25, 50, 75 and 100.
- qcom,qpnp-lab-nfet-size: NFET size in percentage. Supported values
are 25, 50, 75 and 100.
-- qcom,qpnp-lab-max-precharge-time: Precharge time in us of LAB regulator.
+- qcom,qpnp-lab-max-precharge-time: Precharge time in uS for LAB regulator.
Supported values are 200, 300, 400 and 500.
+ Suggested values for LCD and AMOLED mode
+ are 500 and 300uS respectively.
- qcom,qpnp-lab-switching-clock-frequency: The PWM switching clock frequency in
kHz of Lab regulator, Supported values
are: 3200, 2740, 2400, 2130, 1920,
@@ -91,11 +93,22 @@ LAB subnode required properties:
1130, 1070, 1010, 960, 910.
- qcom,qpnp-lab-limit-maximum-current: The maximum inductor current limit in
mA of LAB regulator. Supported values
- are 200, 400, 600 and 800.
+ are 200, 400, 600, 800, 1000, 1200,
+ 1400 and 1600.
+- interrupts: Specify the interrupts as per the interrupt
+ encoding.
+ Currently "lab-vreg-ok" is required for
+ LCD mode in pmicobalt. For AMOLED mode,
+ "lab-vreg-ok" is required only when SWIRE
+ control is enabled and skipping 2nd SWIRE
+ pulse is required in pmi8952/8996.
+- interrupt-names: Interrupt names to match up 1-to-1 with
+ the interrupts specified in 'interrupts'
+ property.
LAB subnode optional properties:
-- qpnp,qpnp-lab-current-sense: If this property is specified, the LAB current
+- qcom,qpnp-lab-current-sense: If this property is specified, the LAB current
sense gain will be programmed for LAB regulator.
Otherwise, LAB current sense gain will be
default to "1x". A string is used to specify the
@@ -209,7 +222,7 @@ IBB subnode optional properties:
any value in the allowed limit.
- qcom,output-voltage-one-pulse The expected voltage (in mV) of VDISN signal
on the first SWIRE pulse. This property
- can be specified only if 'qpnp,swire-control'
+ can be specified only if 'qcom,swire-control'
is defined. The minimum and maximum values
are 1400mV and 7700mV.
@@ -219,7 +232,7 @@ Example:
compatible = "qcom,qpnp-labibb-regulator";
#address-cells = <1>;
#size-cells = <1>;
- qpnp,qpnp-labibb-mode = "lcd";
+ qcom,qpnp-labibb-mode = "lcd";
qcom,pmic-revid = <&pmi8994_revid>;
qcom,skip-2nd-swire-cmd;
@@ -227,7 +240,8 @@ Example:
reg = <0xde00 0x100>;
reg-names = "lab";
- interrupts = <0x3 0xde 0x0>;
+ interrupts = <0x3 0xde 0x0
+ IRQ_TYPE_EDGE_RISING>;
interrupt-names = "lab-vreg-ok";
regulator-name = "lab_reg";
@@ -247,7 +261,7 @@ Example:
qcom,qpnp-lab-full-pull-down;
qcom,qpnp-lab-pull-down-enable;
qcom,qpnp-lab-switching-clock-frequency = <1600>;
- qcom,qpnp-lab-limit-maximum-current = <800>;
+ qcom,qpnp-lab-limit-maximum-current = <1600>;
qcom,qpnp-lab-limit-max-current-enable;
qcom,qpnp-lab-ps-threshold = <40>;
qcom,qpnp-lab-ps-enable;
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index 82befcbd24a3..c3d58ce2c864 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -1606,6 +1606,130 @@ Example:
asoc-wsa-codec-prefixes = "SpkrMono";
};
+* MSMFALCON ASoC Machine driver
+
+Required properties:
+- compatible : "qcom,msmfalcon-asoc-snd"
+- qcom,model : The user-visible name of this sound card.
+- qcom,msm-hs-micbias-type : This property is used to recognize the headset
+ micbias type, internal or external.
+- qcom,msm-mbhc-hphl-swh: This property is used to distinguish headset HPHL
+switch type on target typically the switch type will be normally open or
+normally close, value for this property 0 for normally close and 1 for
+normally open.
+- qcom,msm-mbhc-gnd-swh: This property is used to distinguish headset GND
+switch type on target typically the switch type will be normally open or
+normally close, value for this property 0 for normally close and 1 for
+normally open.
+- qcom,audio-routing : A list of the connections between audio components.
+- qcom,msm-gpios : Lists down all the gpio sets that are supported.
+- qcom,pinctrl-names : Lists all the possible combinations of the gpio sets
+mentioned in qcom,msm-gpios.
+- pinctrl-names : The combinations of gpio sets from above that are supported in
+the flavor.
+- pinctrl-# : Pinctrl states as mentioned in pinctrl-names.
+
+Optional properties:
+- qcom,cdc-us-euro-gpios : GPIO on which gnd/mic swap signal is coming.
+- qcom,msm-micbias1-ext-cap : Boolean. Enable micbias1 external
+capacitor mode.
+- qcom,msm-micbias2-ext-cap : Boolean. Enable micbias2 external
+capacitor mode.
+- qcom,msm-spk-ext-pa : GPIO which enables external speaker pa.
+- qcom,msm-mclk-freq : This property is used to inform machine driver about
+mclk frequency needs to be configured for internal and external PA.
+- asoc-platform: This is phandle list containing the references to platform device
+ nodes that are used as part of the sound card dai-links.
+- asoc-platform-names: This property contains list of platform names. The order of
+ the platform names should match to that of the phandle order
+ given in "asoc-platform".
+- asoc-cpu: This is phandle list containing the references to cpu dai device nodes
+ that are used as part of the sound card dai-links.
+- asoc-cpu-names: This property contains list of cpu dai names. The order of the
+ cpu dai names should match to that of the phandle order given.
+- asoc-codec: This is phandle list containing the references to codec dai device
+ nodes that are used as part of the sound card dai-links.
+- asoc-codec-names: This property contains list of codec dai names. The order of the
+ codec dai names should match to that of the phandle order given
+ in "asoc-codec".
+- qcom,wsa-max-devs : Maximum number of WSA881x devices present in the target
+- qcom,wsa-devs : List of phandles for all possible WSA881x devices supported for the target
+- qcom,wsa-aux-dev-prefix : Name prefix with Left/Right configuration for WSA881x device
+
+Example:
+ sound {
+ compatible = "qcom,msmfalcon-asoc-snd";
+ qcom,model = "msmfalcon-snd-card";
+ qcom,msm-mclk-freq = <9600000>;
+ qcom,msm-mbhc-hphl-swh = <0>;
+ qcom,msm-mbhc-gnd-swh = <0>;
+ qcom,msm-hs-micbias-type = "internal";
+ qcom,msm-micbias1-ext-cap;
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "SPK_RX_BIAS", "MCLK",
+ "INT_LDO_H", "MCLK",
+ "MIC BIAS External", "Handset Mic",
+ "MIC BIAS Internal2", "Headset Mic",
+ "MIC BIAS External", "Secondary Mic",
+ "AMIC1", "MIC BIAS External",
+ "AMIC2", "MIC BIAS Internal2",
+ "AMIC3", "MIC BIAS External";
+ qcom,msm-gpios =
+ "int_pdm",
+ "us_eu_gpio";
+ qcom,pinctrl-names =
+ "all_off",
+ "int_pdm_act",
+ "us_eu_gpio_act",
+ "int_pdm_us_eu_gpio_act";
+ pinctrl-names =
+ "all_off",
+ "int_pdm_act",
+ "us_eu_gpio_act",
+ "int_pdm_us_eu_gpio_act";
+ pinctrl-0 = <&cdc_pdm_lines_sus &cdc_pdm_lines_2_sus &cross_conn_det_sus>;
+ pinctrl-1 = <&cdc_pdm_lines_act &cdc_pdm_lines_2_act &cross_conn_det_sus>;
+ pinctrl-2 = <&cdc_pdm_lines_sus &cdc_pdm_lines_2_sus &cross_conn_det_act>;
+ pinctrl-3 = <&cdc_pdm_lines_act &cdc_pdm_lines_2_act &cross_conn_det_act>;
+ qcom,cdc-us-euro-gpios = <&msm_gpio 63 0>;
+ asoc-platform = <&pcm0>, <&pcm1>, <&voip>, <&voice>,
+ <&loopback>, <&compress>, <&hostless>,
+ <&afe>, <&lsm>, <&routing>, <&lpa>;
+ asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
+ "msm-voip-dsp", "msm-pcm-voice", "msm-pcm-loopback",
+ "msm-compress-dsp", "msm-pcm-hostless", "msm-pcm-afe",
+ "msm-lsm-client", "msm-pcm-routing", "msm-pcm-lpa";
+ asoc-cpu = <&dai_pri_auxpcm>, <&dai_hdmi>,
+ <&dai_mi2s0>, <&dai_mi2s1>, <&dai_mi2s2>, <&dai_mi2s3>,
+ <&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>,
+ <&sb_3_rx>, <&sb_3_tx>, <&sb_4_rx>, <&sb_4_tx>,
+ <&bt_sco_rx>, <&bt_sco_tx>, <&int_fm_rx>, <&int_fm_tx>,
+ <&afe_pcm_rx>, <&afe_pcm_tx>, <&afe_proxy_rx>, <&afe_proxy_tx>,
+ <&incall_record_rx>, <&incall_record_tx>, <&incall_music_rx>,
+ <&incall_music_2_rx>;
+ asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-hdmi.8",
+ "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1",
+ "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
+ "msm-dai-q6-dev.16384", "msm-dai-q6-dev.16385",
+ "msm-dai-q6-dev.16386", "msm-dai-q6-dev.16387",
+ "msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391",
+ "msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393",
+ "msm-dai-q6-dev.12288", "msm-dai-q6-dev.12289",
+ "msm-dai-q6-dev.12292", "msm-dai-q6-dev.12293",
+ "msm-dai-q6-dev.224", "msm-dai-q6-dev.225",
+ "msm-dai-q6-dev.241", "msm-dai-q6-dev.240",
+ "msm-dai-q6-dev.32771", "msm-dai-q6-dev.32772",
+ "msm-dai-q6-dev.32773", "msm-dai-q6-dev.32770";
+ asoc-codec = <&stub_codec>;
+ asoc-codec-names = "msm-stub-codec.1";
+ qcom,wsa-max-devs = <2>;
+ qcom,wsa-devs = <&wsa881x_211>, <&wsa881x_212>,
+ <&wsa881x_213>, <&wsa881x_214>;
+ qcom,wsa-aux-dev-prefix = "SpkrRight", "SpkrLeft",
+ "SpkrRight", "SpkrLeft";
+ };
+
* MSM8952 Slimbus ASoC Machine driver
Required properties:
@@ -2032,6 +2156,139 @@ Example:
asoc-codec-names = "msm-stub-codec.1";
};
+* MSMFALCON ASoC Slimbus Machine driver
+
+Required properties:
+- compatible : "qcom,msmfalcon-asoc-snd-tasha" for tasha codec,
+ "qcom,msmfalcon-asoc-snd-tavil" for tavil codec.
+- qcom,model : The user-visible name of this sound card.
+- qcom,msm-mclk-freq : MCLK frequency value for external codec
+- qcom,msm-gpios : Lists down all the gpio sets that are supported.
+- qcom,pinctrl-names : Lists all the possible combinations of the gpio sets
+mentioned in qcom,msm-gpios. Say we have 2^N combinations for N GPIOs,
+this would list all the 2^N combinations.
+- pinctrl-names : The combinations of gpio sets from above that are supported in
+the flavor. This can be sometimes same as qcom, pinctrl-names i.e with 2^N
+combinations or will have less incase if some combination is not supported.
+- pinctrl-# : Pinctrl states as mentioned in pinctrl-names.
+- qcom,audio-routing : A list of the connections between audio components.
+- asoc-platform: This is phandle list containing the references to platform device
+ nodes that are used as part of the sound card dai-links.
+- asoc-platform-names: This property contains list of platform names. The order of
+ the platform names should match to that of the phandle order
+ given in "asoc-platform".
+- asoc-cpu: This is phandle list containing the references to cpu dai device nodes
+ that are used as part of the sound card dai-links.
+- asoc-cpu-names: This property contains list of cpu dai names. The order of the
+ cpu dai names should match to that of the phandle order given
+ in "asoc-cpu". The cpu names are in the form of "%s.%d" form,
+ where the id (%d) field represents the back-end AFE port id that
+ this CPU dai is associated with.
+- asoc-codec: This is phandle list containing the references to codec dai device
+ nodes that are used as part of the sound card dai-links.
+- asoc-codec-names: This property contains list of codec dai names. The order of the
+ codec dai names should match to that of the phandle order given
+ in "asoc-codec".
+Optional properties:
+- qcom,cdc-us-euro-gpios : GPIO on which gnd/mic swap signal is coming.
+- clock-names : clock name defined for external clock.
+- clocks : external clock defined for codec clock.
+- qcom,wsa-max-devs : Maximum number of WSA881x devices present in the target
+- qcom,wsa-devs : List of phandles for all possible WSA881x devices supported for the target
+- qcom,wsa-aux-dev-prefix : Name prefix with Left/Right configuration for WSA881x device
+
+Example:
+
+ sound-9335 {
+ compatible = "qcom,msmfalcon-asoc-snd-tasha";
+ qcom,model = "msmfalcon-tasha-snd-card";
+
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "AIF4 MAD", "MCLK",
+ "ultrasound amp", "LINEOUT1",
+ "ultrasound amp", "LINEOUT3",
+ "AMIC1", "MIC BIAS1 Internal1",
+ "MIC BIAS1 Internal1", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC3", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCRight Headset Mic",
+ "AMIC4", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCLeft Headset Mic",
+ "DMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic1",
+ "DMIC2", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic2",
+ "DMIC3", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic3",
+ "DMIC4", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic4",
+ "DMIC5", "MIC BIAS4 External",
+ "MIC BIAS4 External", "Digital Mic5",
+ "DMIC6", "MIC BIAS4 External",
+ "MIC BIAS4 External", "Digital Mic6";
+
+ qcom,msm-mbhc-hphl-swh = <0>;
+ qcom,msm-mbhc-gnd-swh = <0>;
+ qcom,msm-mclk-freq = <9600000>;
+ qcom,msm-gpios =
+ "slim",
+ "us_eu_gpio";
+ qcom,pinctrl-names =
+ "all_off",
+ "slim_act",
+ "us_eu_gpio_act",
+ "slim_us_eu_gpio_act";
+ pinctrl-names =
+ "all_off",
+ "slim_act",
+ "us_eu_gpio_act",
+ "slim_us_eu_gpio_act";
+ pinctrl-0 = <&cdc_slim_lines_sus &cross_conn_det_sus>;
+ pinctrl-1 = <&cdc_slim_lines_act &cross_conn_det_sus>;
+ pinctrl-2 = <&cdc_slim_lines_sus &cross_conn_det_act>;
+ pinctrl-3 = <&cdc_slim_lines_act &cross_conn_det_act>;
+ qcom,cdc-us-euro-gpios = <&msm_gpio 63 0>;
+ asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
+ <&loopback>, <&compress>, <&hostless>,
+ <&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>;
+ asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
+ "msm-pcm-dsp.2", "msm-voip-dsp",
+ "msm-pcm-voice", "msm-pcm-loopback",
+ "msm-compress-dsp", "msm-pcm-hostless",
+ "msm-pcm-afe", "msm-lsm-client",
+ "msm-pcm-routing", "msm-cpe-lsm",
+ "msm-compr-dsp";
+ asoc-cpu = <&dai_hdmi>,
+ <&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>,
+ <&sb_2_rx>, <&sb_2_tx>, <&sb_3_rx>, <&sb_3_tx>,
+ <&sb_4_rx>, <&sb_4_tx>, <&sb_5_tx>,
+ <&afe_pcm_rx>, <&afe_pcm_tx>, <&afe_proxy_rx>,
+ <&afe_proxy_tx>, <&incall_record_rx>,
+ <&incall_record_tx>, <&incall_music_rx>,
+ <&incall_music_2_rx>, <&sb_5_rx>;
+ asoc-cpu-names = "msm-dai-q6-hdmi.8",
+ "msm-dai-q6-dev.16384", "msm-dai-q6-dev.16385",
+ "msm-dai-q6-dev.16386", "msm-dai-q6-dev.16387",
+ "msm-dai-q6-dev.16388", "msm-dai-q6-dev.16389",
+ "msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391",
+ "msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393",
+ "msm-dai-q6-dev.16395", "msm-dai-q6-dev.224",
+ "msm-dai-q6-dev.225", "msm-dai-q6-dev.241",
+ "msm-dai-q6-dev.240", "msm-dai-q6-dev.32771",
+ "msm-dai-q6-dev.32772", "msm-dai-q6-dev.32773",
+ "msm-dai-q6-dev.32770", "msm-dai-q6-dev.16394";
+ asoc-codec = <&stub_codec>;
+ asoc-codec-names = "msm-stub-codec.1";
+ qcom,wsa-max-devs = <2>;
+ qcom,wsa-devs = <&wsa881x_211>, <&wsa881x_212>,
+ <&wsa881x_213>, <&wsa881x_214>;
+ qcom,wsa-aux-dev-prefix = "SpkrRight", "SpkrLeft",
+ "SpkrRight", "SpkrLeft";
+ };
+
* MSMCOBALT ASoC Machine driver
Required properties:
diff --git a/Documentation/scheduler/sched-hmp.txt b/Documentation/scheduler/sched-hmp.txt
index 298064bc44d7..091d49ea80cf 100644
--- a/Documentation/scheduler/sched-hmp.txt
+++ b/Documentation/scheduler/sched-hmp.txt
@@ -31,6 +31,7 @@ CONTENTS
6.1 Per-CPU Window-Based Stats
6.2 Per-task Window-Based Stats
6.3 Effect of various task events
+ 6.4 Tying it all together
7. Tunables
8. HMP Scheduler Trace Points
8.1 sched_enq_deq_task
@@ -872,11 +873,17 @@ both in what they mean and also how they are derived.
*** 6.1 Per-CPU Window-Based Stats
-In addition to the per-task window-based demand, the HMP scheduler
-extensions also track the aggregate demand seen on each CPU. This is
-done using the same windows that the task demand is tracked with
-(which is in turn set by the governor when frequency guidance is in
-use). There are four quantities maintained for each CPU by the HMP scheduler:
+The scheduler tracks two separate types of quantities on a per CPU basis.
+The first type has to deal with the aggregate load on a CPU and the second
+type deals with top-tasks on that same CPU. We will first proceed to explain
+what is maintained as part of each type of statistics and then provide the
+connection between these two types of statistics at the end.
+
+First lets describe the HMP scheduler extensions to track the aggregate load
+seen on each CPU. This is done using the same windows that the task demand
+is tracked with (which is in turn set by the governor when frequency guidance
+is in use). There are four quantities maintained for each CPU by the HMP
+scheduler for tracking CPU load:
curr_runnable_sum: aggregate demand from all tasks which executed during
the current (not yet completed) window
@@ -903,24 +910,86 @@ A 'new' task is defined as a task whose number of active windows since fork is
less than sysctl_sched_new_task_windows. An active window is defined as a window
where a task was observed to be runnable.
+Moving on the second type of statistics; top-tasks, the scheduler tracks a list
+of top tasks per CPU. A top-task is defined as the task that runs the most in a
+given window on that CPU. This includes task that ran on that CPU through out
+the window or were migrated to that CPU prior to window expiration. It does not
+include tasks that were migrated away from that CPU prior to window expiration.
+
+To track top tasks, we first realize that there is no strict need to maintain
+the task struct itself as long as we know the load exerted by the top task. We
+also realize that to maintain top tasks on every CPU we have to track the
+execution of every single task that runs during the window. The load associated
+with a task needs to be migrated when the task migrates from one CPU to another.
+When the top task migrates away, we need to locate the second top task and so
+on.
+
+Given the above realizations, we use hashmaps to track top task load both
+for the current and the previous window. This hashmap is implemented as an array
+of fixed size. The key of the hashmap is given by
+task_execution_time_in_a_window / array_size. The size of the array (number of
+buckets in the hashmap) dictate the load granularity of each bucket. The value
+stored in each bucket is a refcount of all the tasks that executed long enough
+to be in that bucket. This approach has a few benefits. Firstly, any top task
+stats update now take O(1) time. While task migration is also O(1), it does
+still involve going through up to the size of the array to find the second top
+task. We optimize this search by using bitmaps. The next set bit in the bitmap
+gives the position of the second top task in our hashamp.
+
+Secondly, and more importantly, not having to store the task struct itself
+saves a lot of memory usage in that 1) there is no need to retrieve task structs
+later causing cache misses and 2) we don't have to unnecessarily hold up task
+memory for up to 2 full windows by calling get_task_struct() after a task exits.
+
+Given the motivation above, here are a list of quantities tracked as part of
+per CPU task top-tasks management
+
+ top_tasks[NUM_TRACKED_WINDOWS] - Hashmap of top-task load for the current and
+ previous window
+
+ BITMAP_ARRAY(top_tasks_bitmap) - Two bitmaps for the current and previous
+ windows corresponding to the top-task
+ hashmap.
+
+ load_subs[NUM_TRACKED_WINDOWS] - An array of load subtractions to be carried
+ out form curr/prev_runnable_sums for each CPU
+ prior to reporting load to the governor. The
+ purpose for this will be explained later in
+ the section pertaining to the TASK_MIGRATE
+ event. The type struct load_subtractions,
+ stores the value of the subtraction along
+ with the window start value for the window
+ for which the subtraction has to take place.
+
+
+ curr_table - Indication of which index of the array points to the current
+ window.
+
+ curr_top - The top task on a CPU at any given moment in the current window
+
+ prev_top - The top task on a CPU in the previous window
+
+
*** 6.2 Per-task window-based stats
Corresponding to curr_runnable_sum and prev_runnable_sum, two counters are
maintained per-task
-curr_window - represents cpu demand of task in its most recently tracked
- window
-prev_window - represents cpu demand of task in the window prior to the one
- being tracked by curr_window
+curr_window_cpu - represents task's contribution to cpu busy time on
+ various CPUs in the current window
-The above counters are resued for nt_curr_runnable_sum and
-nt_prev_runnable_sum.
+prev_window_cpu - represents task's contribution to cpu busy time on
+ various CPUs in the previous window
+
+curr_window - represents the sum of all entries in curr_window_cpu
+
+prev_window - represents the sum of all entries in prev_window_cpu
"cpu demand" of a task includes its execution time and can also include its
wait time. 'SCHED_FREQ_ACCOUNT_WAIT_TIME' controls whether task's wait
-time is included in its 'curr_window' and 'prev_window' counters or not.
+time is included in its CPU load counters or not.
-Needless to say, curr_runnable_sum counter of a cpu is derived from curr_window
+Curr_runnable_sum counter of a cpu is derived from curr_window_cpu[cpu]
counter of various tasks that ran on it in its most recent window.
*** 6.3 Effect of various task events
@@ -931,11 +1000,17 @@ PICK_NEXT_TASK
This represents beginning of execution for a task. Provided the task
refers to a non-idle task, a portion of task's wait time that
corresponds to the current window being tracked on a cpu is added to
- task's curr_window counter, provided SCHED_FREQ_ACCOUNT_WAIT_TIME is
- set. The same quantum is also added to cpu's curr_runnable_sum counter.
- The remaining portion, which corresponds to task's wait time in previous
- window is added to task's prev_window and cpu's prev_runnable_sum
- counters.
+ task's curr_window_cpu and curr_window counter, provided
+ SCHED_FREQ_ACCOUNT_WAIT_TIME is set. The same quantum is also added to
+ cpu's curr_runnable_sum counter. The remaining portion, which
+ corresponds to task's wait time in previous window is added to task's
+ prev_window, prev_window_cpu and cpu's prev_runnable_sum counters.
+
+ CPUs top_tasks hashmap is updated if needed with the new information.
+ Any previous entries in the hashmap are deleted and newer entries are
+ created. The top_tasks_bitmap reflects the updated state of the
+ hashmap. If the top task for the current and/or previous window has
+ changed, curr_top and prev_top are updated accordingly.
PUT_PREV_TASK
This represents end of execution of a time-slice for a task, where the
@@ -943,9 +1018,16 @@ PUT_PREV_TASK
or (in case of task being idle with cpu having non-zero rq->nr_iowait
count and sched_io_is_busy =1), a portion of task's execution time, that
corresponds to current window being tracked on a cpu is added to task's
- curr_window_counter and also to cpu's curr_runnable_sum counter. Portion
- of task's execution that corresponds to the previous window is added to
- task's prev_window and cpu's prev_runnable_sum counters.
+ curr_window_cpu and curr_window counter and also to cpu's
+ curr_runnable_sum counter. Portion of task's execution that corresponds
+ to the previous window is added to task's prev_window, prev_window_cpu
+ and cpu's prev_runnable_sum counters.
+
+ CPUs top_tasks hashmap is updated if needed with the new information.
+ Any previous entries in the hashmap are deleted and newer entries are
+ created. The top_tasks_bitmap reflects the updated state of the
+ hashmap. If the top task for the current and/or previous window has
+ changed, curr_top and prev_top are updated accordingly.
TASK_UPDATE
This event is called on a cpu's currently running task and hence
@@ -955,34 +1037,128 @@ TASK_UPDATE
TASK_WAKE
This event signifies a task waking from sleep. Since many windows
- could have elapsed since the task went to sleep, its curr_window
- and prev_window are updated to reflect task's demand in the most
- recent and its previous window that is being tracked on a cpu.
+ could have elapsed since the task went to sleep, its
+ curr_window_cpu/curr_window and prev_window_cpu/prev_window are
+ updated to reflect task's demand in the most recent and its previous
+ window that is being tracked on a cpu. Updated stats will trigger
+ the same book-keeping for top-tasks as other events.
TASK_MIGRATE
This event signifies task migration across cpus. It is invoked on the
task prior to being moved. Thus at the time of this event, the task
can be considered to be in "waiting" state on src_cpu. In that way
this event reflects actions taken under PICK_NEXT_TASK (i.e its
- wait time is added to task's curr/prev_window counters as well
+ wait time is added to task's curr/prev_window/_cpu counters as well
as src_cpu's curr/prev_runnable_sum counters, provided
- SCHED_FREQ_ACCOUNT_WAIT_TIME is non-zero). After that update,
- src_cpu's curr_runnable_sum is reduced by task's curr_window value
- and dst_cpu's curr_runnable_sum is increased by task's curr_window
- value. Similarly, src_cpu's prev_runnable_sum is reduced by task's
- prev_window value and dst_cpu's prev_runnable_sum is increased by
- task's prev_window value.
+ SCHED_FREQ_ACCOUNT_WAIT_TIME is non-zero).
+
+ After that update, we make a distinction between intra-cluster and
+ inter-cluster migrations for further book-keeping.
+
+ For intra-cluster migrations, we simply remove the entry for the task
+ in the top_tasks hashmap from the source CPU and add the entry to the
+ destination CPU. The top_tasks_bitmap, curr_top and prev_top are
+ updated accordingly. We then find the second top-task top in our
+ top_tasks hashmap for both the current and previous window and set
+ curr_top and prev_top to their new values.
+
+ For inter-cluster migrations we have a much more complicated scheme.
+ Firstly we add to the destination CPU's curr/prev_runnable_sum
+ the tasks curr/prev_window. Note we add the sum and not the
+ contribution any individual CPU. This is because when a tasks migrates
+ across clusters, we need the new cluster to ramp up to the appropriate
+ frequency given the task's total execution summed up across all CPUs
+ in the previous cluster.
+
+ Secondly the src_cpu's curr/prev_runnable_sum are reduced by task's
+ curr/prev_window_cpu values.
+
+ Thirdly, we need to walk all the CPUs in the cluster and subtract from
+ each CPU's curr/prev_runnable_sum the task's respective
+ curr/prev_window_cpu values. However, subtracting load from each of
+ the source CPUs is not trivial, as it would require all runqueue
+ locks to be held. To get around this we introduce a deferred load
+ subtraction mechanism whereby subtracting load from each of the source
+ CPUs is deferred until an opportune moment. This opportune moment is
+ when the governor comes asking the scheduler for load. At that time, all
+ necessary runqueue locks are already held.
+
+ There are a few cases to consider when doing deferred subtraction. Since
+ we are not holding all runqueue locks other CPUs in the source cluster
+ can be in a different window than the source CPU where the task is
+ migrating from.
+
+ Case 1:
+ Other CPU in the source cluster is in the same window. No special
+ consideration.
+
+ Case 2:
+ Other CPU in the source cluster is ahead by 1 window. In this
+ case, we will be doing redundant updates to subtraction load for the
+ prev window. There is no way to avoid this redundant update though,
+ without holding the rq lock.
+
+ Case 3:
+ Other CPU in the source cluster is trailing by 1 window In this
+ case, we might end up overwriting old data for that CPU. But this is not
+ a problem as when the other CPU calls update_task_ravg() it will move to
+ the same window. This relies on maintaining synchronized windows between
+ CPUs, which is true today.
+
+ To achieve all the above, we simple add the task's curr/prev_window_cpu
+ contributions to the per CPU load_subtractions array. These load
+ subtractions are subtracted from the respective CPU's
+ curr/prev_runnable_sums before the governor queries CPU load. Once this
+ is complete, the scheduler sets all curr/prev_window_cpu contributions
+ of the task to 0 for all CPUs in the source cluster. The destination
+ CPUs's curr/prev_window_cpu is updated with the tasks curr/prev_window
+ sums.
+
+ Finally, we must deal with frequency aggregation. When frequency
+ aggregation is in effect, there is little point in dealing with per CPU
+ footprint since the load of all related tasks have to be reported on a
+ single CPU. Therefore when a task enters a related group we clear out
+ all per CPU contributions and add it to the task CPU's cpu_time struct.
+ From that point onwards we stop managing per CPU contributions upon
+ inter cluster migrations since that work is redundant. Finally when a
+ task exits a related group we must walk every CPU in reset all CPU
+ contributions. We then set the task CPU contribution to the respective
+ curr/prev sum values and add that sum to the task CPU rq runnable sum.
+
+ Top-task management is the same as in the case of intra-cluster
+ migrations.
IRQ_UPDATE
This event signifies end of execution of an interrupt handler. This
event results in update of cpu's busy time counters, curr_runnable_sum
- and prev_runnable_sum, provided cpu was idle.
- When sched_io_is_busy = 0, only the interrupt handling time is added
- to cpu's curr_runnable_sum and prev_runnable_sum counters. When
- sched_io_is_busy = 1, the event mirrors actions taken under
- TASK_UPDATED event i.e time since last accounting of idle task's cpu
- usage is added to cpu's curr_runnable_sum and prev_runnable_sum
- counters.
+ and prev_runnable_sum, provided cpu was idle. When sched_io_is_busy = 0,
+ only the interrupt handling time is added to cpu's curr_runnable_sum and
+ prev_runnable_sum counters. When sched_io_is_busy = 1, the event mirrors
+ actions taken under TASK_UPDATED event i.e time since last accounting
+ of idle task's cpu usage is added to cpu's curr_runnable_sum and
+ prev_runnable_sum counters. No update is needed for top-tasks in this
+ case.
+
+*** 6.4 Tying it all together
+
+Now the scheduler maintains two independent quantities for load reporing 1) CPU
+load as represented by prev_runnable_sum and 2) top-tasks. The reported load
+is governed by tunable sched_freq_reporting_policy. The default choice is
+FREQ_REPORT_MAX_CPU_LOAD_TOP_TASK. In other words:
+
+max(prev_runnable_sum, top_task load)
+
+Let's explain the rationale behind the choice. CPU load tracks the exact amount
+of execution observed on a CPU. This is close to the quantity that the vanilla
+governor used to track. It offers the advantages of no load over-reporting that
+our earlier load fixup mechanisms had deal with. It then also tackles the part
+picture problem by keeping of track of tasks that might be migrating across
+CPUs leaving a small footprint on each CPU. Since we maintain one top task per
+CPU, we can handle as many top tasks as the number of CPUs in a cluster. We
+might miss a few cases where the combined load of the top and non-top tasks on
+a CPU are more representative of the true load. However, those cases have been
+deemed to rare and have little impact on overall load/frequency behavior.
+
===========
7. TUNABLES
@@ -1238,6 +1414,18 @@ However LPM exit latency associated with an idle CPU outweigh the above
benefits on some targets. When this knob is turned on, the waker CPU is
selected if it has only 1 runnable task.
+*** 7.20 sched_freq_reporting_policy
+
+Appears at: /proc/sys/kernel/sched_freq_reporting_policy
+
+Default value: 0
+
+This dictates what the load reporting policy to the governor should be. The
+default value is FREQ_REPORT_MAX_CPU_LOAD_TOP_TASK. Other values include
+FREQ_REPORT_CPU_LOAD which only reports CPU load to the governor and
+FREQ_REPORT_TOP_TASK which only reports the load of the top task on a CPU
+to the governor.
+
=========================
8. HMP SCHEDULER TRACE POINTS
=========================
@@ -1318,7 +1506,7 @@ frequency of the CPU for real time task placement).
Logged when window-based stats are updated for a task. The update may happen
for a variety of reasons, see section 2.5, "Task Events."
-<idle>-0 [004] d.h4 12700.711513: sched_update_task_ravg: wc 12700711473496 ws 12700691772135 delta 19701361 event TASK_WAKE cpu 4 cur_freq 199200 cur_pid 0 task 13227 (powertop) ms 12640648272532 delta 60063200964 demand 13364423 sum 0 irqtime 0 cs 0 ps 495018 cur_window 0 prev_window 0
+rcu_preempt-7 [000] d..3 262857.738888: sched_update_task_ravg: wc 262857521127957 ws 262857490000000 delta 31127957 event PICK_NEXT_TASK cpu 0 cur_freq 291055 cur_pid 7 task 9309 (kworker/u16:0) ms 262857520627280 delta 500677 demand 282196 sum 156201 irqtime 0 pred_demand 267103 rq_cs 478718 rq_ps 0 cur_window 78433 (78433 0 0 0 0 0 0 0 ) prev_window 146430 (0 146430 0 0 0 0 0 0 ) nt_cs 0 nt_ps 0 active_wins 149 grp_cs 0 grp_ps 0, grp_nt_cs 0, grp_nt_ps: 0 curr_top 6 prev_top 2
- wc: wallclock, output of sched_clock(), monotonically increasing time since
boot (will roll over in 585 years) (ns)
@@ -1344,9 +1532,27 @@ for a variety of reasons, see section 2.5, "Task Events."
counter.
- ps: prev_runnable_sum of cpu (ns). See section 6.1 for more details of this
counter.
-- cur_window: cpu demand of task in its most recently tracked window (ns)
-- prev_window: cpu demand of task in the window prior to the one being tracked
- by cur_window
+- cur_window: cpu demand of task in its most recently tracked window summed up
+ across all CPUs (ns). This is followed by a list of contributions on each
+ individual CPU.
+- prev_window: cpu demand of task in its previous window summed up across
+ all CPUs (ns). This is followed by a list of contributions on each individual
+ CPU.
+- nt_cs: curr_runnable_sum of a cpu for new tasks only (ns).
+- nt_ps: prev_runnable_sum of a cpu for new tasks only (ns).
+- active_wins: No. of active windows since task statistics were initialized
+- grp_cs: curr_runnable_sum for colocated tasks. This is independent from
+ cs described above. The addition of these two fields give the total CPU
+ load for the most recent window
+- grp_ps: prev_runnable_sum for colocated tasks. This is independent from
+ ps described above. The addition of these two fields give the total CPU
+ load for the previous window.
+- grp_nt_cs: curr_runnable_sum of a cpu for grouped new tasks only (ns).
+- grp_nt_ps: prev_runnable_sum for a cpu for grouped new tasks only (ns).
+- curr_top: index of the top task in the top_tasks array in the current
+ window for a CPU.
+- prev_top: index of the top task in the top_tasks array in the previous
+ window for a CPU
*** 8.5 sched_update_history
diff --git a/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi b/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi
index 9083c89802f3..70156b1f8493 100644
--- a/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi
+++ b/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi
@@ -361,7 +361,7 @@
&labibb {
status = "ok";
- qpnp,qpnp-labibb-mode = "lcd";
+ qcom,qpnp-labibb-mode = "lcd";
};
&ibb_regulator {
diff --git a/arch/arm/boot/dts/qcom/apq8096-dragonboard.dtsi b/arch/arm/boot/dts/qcom/apq8096-dragonboard.dtsi
index a2085945ac33..a7482bcce112 100644
--- a/arch/arm/boot/dts/qcom/apq8096-dragonboard.dtsi
+++ b/arch/arm/boot/dts/qcom/apq8096-dragonboard.dtsi
@@ -361,7 +361,7 @@
&labibb {
status = "ok";
- qpnp,qpnp-labibb-mode = "lcd";
+ qcom,qpnp-labibb-mode = "lcd";
};
&rpm_bus {
diff --git a/arch/arm/boot/dts/qcom/apq8096-sbc.dtsi b/arch/arm/boot/dts/qcom/apq8096-sbc.dtsi
index 4e7379d9e164..0ee28c2c427e 100644
--- a/arch/arm/boot/dts/qcom/apq8096-sbc.dtsi
+++ b/arch/arm/boot/dts/qcom/apq8096-sbc.dtsi
@@ -364,7 +364,7 @@
&labibb {
status = "ok";
- qpnp,qpnp-labibb-mode = "lcd";
+ qcom,qpnp-labibb-mode = "lcd";
};
&ibb_regulator {
diff --git a/arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi b/arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi
index 76126c21c43a..8bf98d83d381 100644
--- a/arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi
+++ b/arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi
@@ -18,44 +18,44 @@ qcom,qrd_msmcobalt_skuk_3000mah {
qcom,battery-type = "qrd_msmcobalt_skuk_300mah";
qcom,checksum = <0x0F19>;
qcom,fg-profile-data = [
- 05 B2 1F 6F
- FC A3 0A 6E
- FD DB 1D 8C
- 1D AE 12 C2
- 23 00 18 7E
- 52 B4 45 8D
- 00 00 00 55
- 00 00 00 0F
- C5 92 00 00
- CA A0 CD 95
- 00 0C 00 1F
- EC C3 F2 56
- F3 27 06 7B
- 12 FF 01 02
- 3A 21 DA 1C
- 40 40 09 1C
- 00 05 00 07
- 05 B4 1F AC
- FC EF 0A 57
- 00 2E 1D 6A
- 14 BA 0B 12
- 22 DC 19 40
- 53 03 45 79
- 00 00 00 53
- 00 00 00 0E
- CC 05 00 00
- CA 24 BB 3A
- 00 00 00 1C
- EC C3 F2 56
- F2 A2 06 A6
- 01 C7 06 96
- 1A CF EA 8B
- 33 08 33 BA
- 00 00 10 07
- 46 66 0C 3A
- 00 19 00 1C
- FA 0A 01 98
- 00 00 00 FF
+ 6F 1F B2 05
+ 6E 0A A3 FC
+ 8C 1D DB FD
+ C2 12 AE 1D
+ 7E 18 00 23
+ 8D 45 B4 52
+ 55 00 00 00
+ 0F 00 00 00
+ 00 00 92 C5
+ 95 CD A0 CA
+ 1F 00 0C 00
+ 56 F2 C3 EC
+ 7B 06 27 F3
+ 02 01 FF 12
+ 1C DA 21 3A
+ 1C 09 40 40
+ 07 00 05 00
+ AC 1F B4 05
+ 57 0A EF FC
+ 6A 1D 2E 00
+ 12 0B BA 14
+ 40 19 DC 22
+ 79 45 03 53
+ 53 00 00 00
+ 0E 00 00 00
+ 00 00 05 CC
+ 3A BB 24 CA
+ 1C 00 00 00
+ 56 F2 C3 EC
+ A6 06 A2 F2
+ 96 06 C7 01
+ 8B EA CF 1A
+ BA 33 08 33
+ 07 10 00 00
+ 3A 0C 66 46
+ 1C 00 19 00
+ 98 01 0A FA
+ FF 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-cmd.dtsi
index 9ad9e4adce00..94ca102c9dc0 100644
--- a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-cmd.dtsi
+++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-cmd.dtsi
@@ -44,6 +44,8 @@
qcom,mdss-dsi-dma-trigger = "trigger_sw";
qcom,mdss-dsi-mdp-trigger = "none";
qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>;
+ qcom,mdss-pan-physical-width-dimension = <74>;
+ qcom,mdss-pan-physical-height-dimension = <131>;
qcom,mdss-dsi-te-pin-select = <1>;
qcom,mdss-dsi-wr-mem-start = <0x2c>;
qcom,mdss-dsi-wr-mem-continue = <0x3c>;
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-video.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-video.dtsi
index 6b549a4af6eb..49130cc96f79 100644
--- a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-video.dtsi
+++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-video.dtsi
@@ -77,6 +77,8 @@
qcom,mdss-dsi-dma-trigger = "trigger_sw";
qcom,mdss-dsi-mdp-trigger = "none";
qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>;
+ qcom,mdss-pan-physical-width-dimension = <74>;
+ qcom,mdss-pan-physical-height-dimension = <131>;
qcom,compression-mode = "dsc";
qcom,config-select = <&dsi_nt35597_dsc_video_config0>;
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-cmd.dtsi
index 1e42d0846acf..10be9cc183f6 100644
--- a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-cmd.dtsi
+++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-cmd.dtsi
@@ -47,6 +47,8 @@
04 00];
qcom,adjust-timer-wakeup-ms = <1>;
qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>;
+ qcom,mdss-pan-physical-width-dimension = <74>;
+ qcom,mdss-pan-physical-height-dimension = <131>;
qcom,mdss-dsi-t-clk-post = <0x0d>;
qcom,mdss-dsi-t-clk-pre = <0x2d>;
qcom,mdss-dsi-bl-max-level = <4095>;
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 82413bfbca89..a2cac50325c5 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
@@ -70,6 +70,8 @@
qcom,mdss-dsi-dma-trigger = "trigger_sw";
qcom,mdss-dsi-mdp-trigger = "none";
qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>;
+ qcom,mdss-pan-physical-width-dimension = <74>;
+ qcom,mdss-pan-physical-height-dimension = <131>;
qcom,mdss-dsi-min-refresh-rate = <55>;
qcom,mdss-dsi-max-refresh-rate = <60>;
qcom,mdss-dsi-pan-enable-dynamic-fps;
diff --git a/arch/arm/boot/dts/qcom/msm-pm2falcon-rpm-regulator.dtsi b/arch/arm/boot/dts/qcom/msm-pm2falcon-rpm-regulator.dtsi
new file mode 100644
index 000000000000..f500079e6953
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msm-pm2falcon-rpm-regulator.dtsi
@@ -0,0 +1,238 @@
+/* Copyright (c) 2016, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&rpm_bus {
+ rpm-regulator-smpb1 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "smpb";
+ qcom,resource-id = <1>;
+ qcom,regulator-type = <1>;
+ status = "disabled";
+
+ regulator-s1 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_s1";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-smpb2 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "smpb";
+ qcom,resource-id = <2>;
+ qcom,regulator-type = <1>;
+ status = "disabled";
+
+ regulator-s2 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_s2";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-smpb3 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "smpb";
+ qcom,resource-id = <3>;
+ qcom,regulator-type = <1>;
+ status = "disabled";
+
+ regulator-s3 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_s3";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-smpb5 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "smpb";
+ qcom,resource-id = <5>;
+ qcom,regulator-type = <1>;
+ status = "disabled";
+
+ regulator-s5 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_s5";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldob1 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldob";
+ qcom,resource-id = <1>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l1 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_l1";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldob2 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldob";
+ qcom,resource-id = <2>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l2 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_l2";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldob3 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldob";
+ qcom,resource-id = <3>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l3 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_l3";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldob4 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldob";
+ qcom,resource-id = <4>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l4 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_l4";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldob5 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldob";
+ qcom,resource-id = <5>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l5 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_l5";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldob6 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldob";
+ qcom,resource-id = <6>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l6 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_l6";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldob7 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldob";
+ qcom,resource-id = <7>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l7 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_l7";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldob8 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldob";
+ qcom,resource-id = <8>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l8 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_l8";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldob9 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "rwsc";
+ qcom,resource-id = <9>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l9 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_l9";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldob10 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "rwsm";
+ qcom,resource-id = <10>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l10 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_l10";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-bobb {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "bobb";
+ qcom,resource-id = <1>;
+ qcom,regulator-type = <4>;
+ status = "disabled";
+
+ regulator-bob {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_bob";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi b/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi
index 41589d02f6fc..79883db10d06 100644
--- a/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi
@@ -234,7 +234,7 @@
linux,name = "wled";
linux,default-trigger = "bkl-trigger";
qcom,fdbk-output = "auto";
- qcom,vref-mv = <350>;
+ qcom,vref-uv = <127500>;
qcom,switch-freq-khz = <800>;
qcom,ovp-mv = <29600>;
qcom,ilim-ma = <970>;
@@ -269,6 +269,7 @@
qcom,thermal-derate-en;
qcom,thermal-derate-current = <200 500 1000>;
qcom,isc-delay = <192>;
+ qcom,pmic-revid = <&pm2falcon_revid>;
status = "disabled";
pm2falcon_flash0: qcom,flash_0 {
@@ -357,10 +358,6 @@
qcom,led-name = "led:switch_0";
qcom,led-mask = <3>;
qcom,default-led-trigger = "switch0_trigger";
- reg0 {
- regulator-name = "pmfalcon_bob";
- max-voltage-uv = <3600000>;
- };
};
pm2falcon_switch1: qcom,led_switch_1 {
@@ -368,10 +365,6 @@
qcom,led-name = "led:switch_1";
qcom,led-mask = <4>;
qcom,default-led-trigger = "switch1_trigger";
- reg0 {
- regulator-name = "pmfalcon_bob";
- max-voltage-uv = <3600000>;
- };
};
};
};
diff --git a/arch/arm/boot/dts/qcom/msm-pmfalcon-rpm-regulator.dtsi b/arch/arm/boot/dts/qcom/msm-pmfalcon-rpm-regulator.dtsi
new file mode 100644
index 000000000000..0b625bf04ef5
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msm-pmfalcon-rpm-regulator.dtsi
@@ -0,0 +1,298 @@
+/* Copyright (c) 2016, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&rpm_bus {
+ rpm-regulator-smpa4 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "smpa";
+ qcom,resource-id = <4>;
+ qcom,regulator-type = <1>;
+ status = "disabled";
+
+ regulator-s4 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_s4";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-smpa5 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "smpa";
+ qcom,resource-id = <5>;
+ qcom,regulator-type = <1>;
+ status = "disabled";
+
+ regulator-s5 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_s5";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-smpa6 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "smpa";
+ qcom,resource-id = <6>;
+ qcom,regulator-type = <1>;
+ status = "disabled";
+
+ regulator-s6 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_s6";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa1 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <1>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l1 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l1";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa2 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <2>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l2 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l2";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa3 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <3>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l3 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l3";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa5 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <5>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l5 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l5";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa6 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <6>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l6 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l6";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa7 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <7>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l7 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l7";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa8 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <8>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l8 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l8";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa9 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <9>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l9 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l9";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa10 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <10>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l10 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l10";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa11 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <11>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l11 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l11";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa12 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <12>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l12 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l12";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa13 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <13>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l13 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l13";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa14 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <14>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l14 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l14";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa15 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <15>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l15 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l15";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa17 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <17>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l17 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l17";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+
+ rpm-regulator-ldoa19 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <19>;
+ qcom,regulator-type = <0>;
+ status = "disabled";
+
+ regulator-l19 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l19";
+ qcom,set = <3>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi b/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi
index bba70329c819..c820d213165b 100644
--- a/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi
@@ -497,7 +497,7 @@
qcom,qpnp-lab-pull-down-enable;
qcom,qpnp-lab-switching-clock-frequency =
<1600>;
- qcom,qpnp-lab-limit-maximum-current = <800>;
+ qcom,qpnp-lab-limit-maximum-current = <1600>;
qcom,qpnp-lab-limit-max-current-enable;
qcom,qpnp-lab-ps-threshold = <20>;
qcom,qpnp-lab-ps-enable;
@@ -523,7 +523,7 @@
linux,name = "wled";
linux,default-trigger = "bkl-trigger";
qcom,fdbk-output = "auto";
- qcom,vref-mv = <350>;
+ qcom,vref-uv = <350000>;
qcom,switch-freq-khz = <800>;
qcom,ovp-mv = <29500>;
qcom,ilim-ma = <980>;
diff --git a/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi b/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi
index f4ca25668814..baeda86bc976 100644
--- a/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi
@@ -555,6 +555,9 @@
regulator-min-microvolt = <4600000>;
regulator-max-microvolt = <6000000>;
+ interrupts = <0x3 0xde 0x0
+ IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "lab-vreg-ok";
qcom,qpnp-lab-min-voltage = <4600000>;
qcom,qpnp-lab-step-size = <100000>;
qcom,qpnp-lab-slew-rate = <5000>;
@@ -569,13 +572,13 @@
qcom,qpnp-lab-pull-down-enable;
qcom,qpnp-lab-switching-clock-frequency =
<1600>;
- qcom,qpnp-lab-limit-maximum-current = <800>;
+ qcom,qpnp-lab-limit-maximum-current = <1600>;
qcom,qpnp-lab-limit-max-current-enable;
qcom,qpnp-lab-ps-threshold = <20>;
qcom,qpnp-lab-ps-enable;
qcom,qpnp-lab-nfet-size = <100>;
qcom,qpnp-lab-pfet-size = <100>;
- qcom,qpnp-lab-max-precharge-time = <300>;
+ qcom,qpnp-lab-max-precharge-time = <500>;
};
};
@@ -595,7 +598,7 @@
linux,name = "wled";
linux,default-trigger = "bkl-trigger";
qcom,fdbk-output = "auto";
- qcom,vref-mv = <350>;
+ qcom,vref-uv = <127500>;
qcom,switch-freq-khz = <800>;
qcom,ovp-mv = <29600>;
qcom,ilim-ma = <970>;
@@ -610,6 +613,7 @@
qcom,led-strings-list = [00 01 02 03];
qcom,en-ext-pfet-sc-pro;
qcom,pmic-revid = <&pmicobalt_revid>;
+ qcom,loop-auto-gm-en;
};
pmicobalt_haptics: qcom,haptic@c000 {
@@ -654,6 +658,7 @@
qcom,thermal-derate-en;
qcom,thermal-derate-current = <200 500 1000>;
qcom,isc-delay = <192>;
+ qcom,pmic-revid = <&pmicobalt_revid>;
pmicobalt_flash0: qcom,flash_0 {
label = "flash";
@@ -741,10 +746,6 @@
qcom,led-name = "led:switch_0";
qcom,led-mask = <3>;
qcom,default-led-trigger = "switch0_trigger";
- reg0 {
- regulator-name = "pmicobalt_bob";
- max-voltage-uv = <3600000>;
- };
};
pmicobalt_switch1: qcom,led_switch_1 {
@@ -752,10 +753,6 @@
qcom,led-name = "led:switch_1";
qcom,led-mask = <4>;
qcom,default-led-trigger = "switch1_trigger";
- reg0 {
- regulator-name = "pmicobalt_bob";
- max-voltage-uv = <3600000>;
- };
};
};
};
diff --git a/arch/arm/boot/dts/qcom/msm8996-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8996-cdp.dtsi
index 1c85e13aa0f8..165c7de039e5 100644
--- a/arch/arm/boot/dts/qcom/msm8996-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-cdp.dtsi
@@ -387,7 +387,7 @@
&labibb {
status = "ok";
- qpnp,qpnp-labibb-mode = "lcd";
+ qcom,qpnp-labibb-mode = "lcd";
};
&dsi_dual_sharp_video {
diff --git a/arch/arm/boot/dts/qcom/msm8996-dtp.dtsi b/arch/arm/boot/dts/qcom/msm8996-dtp.dtsi
index 19d052791c9a..5c62766b1a26 100644
--- a/arch/arm/boot/dts/qcom/msm8996-dtp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-dtp.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -452,7 +452,7 @@
&labibb {
status = "ok";
- qpnp,qpnp-labibb-mode = "lcd";
+ qcom,qpnp-labibb-mode = "lcd";
};
&mdss_mdp {
diff --git a/arch/arm/boot/dts/qcom/msm8996-fluid.dtsi b/arch/arm/boot/dts/qcom/msm8996-fluid.dtsi
index 550da56520f8..baecf4b8574e 100644
--- a/arch/arm/boot/dts/qcom/msm8996-fluid.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-fluid.dtsi
@@ -636,7 +636,7 @@
&labibb {
status = "ok";
- qpnp,qpnp-labibb-mode = "lcd";
+ qcom,qpnp-labibb-mode = "lcd";
};
&pmi8994_mpps {
diff --git a/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi b/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi
index 07423a601b35..215608959dc5 100644
--- a/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi
@@ -129,6 +129,40 @@
vddcx-supply = <&gdsc_gpu>;
vdd-supply = <&gdsc_gpu_gx>;
+ /* GPU Mempools */
+ qcom,gpu-mempools {
+ #address-cells= <1>;
+ #size-cells = <0>;
+ compatible = "qcom,gpu-mempools";
+
+ /* 4K Page Pool configuration */
+ qcom,gpu-mempool@0 {
+ reg = <0>;
+ qcom,mempool-page-size = <4096>;
+ qcom,mempool-reserved = <2048>;
+ qcom,mempool-allocate;
+ };
+ /* 8K Page Pool configuration */
+ qcom,gpu-mempool@1 {
+ reg = <1>;
+ qcom,mempool-page-size = <8192>;
+ qcom,mempool-reserved = <1024>;
+ qcom,mempool-allocate;
+ };
+ /* 64K Page Pool configuration */
+ qcom,gpu-mempool@2 {
+ reg = <2>;
+ qcom,mempool-page-size = <65536>;
+ qcom,mempool-reserved = <256>;
+ };
+ /* 1M Page Pool configuration */
+ qcom,gpu-mempool@3 {
+ reg = <3>;
+ qcom,mempool-page-size = <1048576>;
+ qcom,mempool-reserved = <32>;
+ };
+ };
+
/* Power levels */
qcom,gpu-pwrlevels {
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/qcom/msm8996-liquid.dtsi b/arch/arm/boot/dts/qcom/msm8996-liquid.dtsi
index 33397e3e4762..dae7306cdd07 100644
--- a/arch/arm/boot/dts/qcom/msm8996-liquid.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-liquid.dtsi
@@ -319,7 +319,7 @@
&labibb {
status = "ok";
- qpnp,qpnp-labibb-mode = "lcd";
+ qcom,qpnp-labibb-mode = "lcd";
};
&dsi_dual_jdi_4k_nofbc_video {
diff --git a/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi
index 07cb98860498..27d3eea5bc20 100644
--- a/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi
@@ -368,7 +368,7 @@
&labibb {
status = "ok";
- qpnp,qpnp-labibb-mode = "lcd";
+ qcom,qpnp-labibb-mode = "lcd";
};
&dsi_dual_sharp_video {
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-camera-sensor-qrd-vr1.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-camera-sensor-qrd-vr1.dtsi
new file mode 100644
index 000000000000..0fb1a0425dd5
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msmcobalt-camera-sensor-qrd-vr1.dtsi
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 2016, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&soc {
+ led_flash0: qcom,camera-flash@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera-flash";
+ qcom,flash-source = <&pmicobalt_flash0 &pmicobalt_flash1>;
+ qcom,switch-source = <&pmicobalt_switch0>;
+ status = "ok";
+ };
+
+ led_flash1: qcom,camera-flash@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera-flash";
+ qcom,flash-source = <&pmicobalt_flash2>;
+ qcom,switch-source = <&pmicobalt_switch1>;
+ status = "ok";
+ };
+};
+
+&tlmm{
+ cam_sensor_front_active: cam_sensor_front_active {
+ /* RESET */
+ mux {
+ pins = "gpio9";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio9";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_front_suspend: cam_sensor_front_suspend {
+ /* RESET */
+ mux {
+ pins = "gpio9";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio9";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_rear2_active: cam_sensor_rear2_active {
+ /* RESET, STANDBY */
+ mux {
+ pins = "gpio27","gpio8";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio27","gpio8";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_rear2_suspend: cam_sensor_rear2_suspend {
+ /* RESET, STANDBY */
+ mux {
+ pins = "gpio27","gpio8";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio27","gpio8";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+};
+
+
+&cci {
+ actuator0: qcom,actuator@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ };
+
+ actuator1: qcom,actuator@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ };
+
+ eeprom0: qcom,eeprom@0 {
+ cell-index = <0>;
+ reg = <0>;
+ compatible = "qcom,eeprom";
+ cam_vio-supply = <&pmcobalt_lvs1>;
+ cam_vana-supply = <&pmicobalt_bob>;
+ cam_vdig-supply = <&pmcobalt_s3>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 3312000 1352000>;
+ qcom,cam-vreg-max-voltage = <0 3600000 1352000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_active
+ &cam_sensor_rear_active>;
+ pinctrl-1 = <&cam_sensor_mclk0_suspend
+ &cam_sensor_rear_suspend>;
+ gpios = <&tlmm 13 0>,
+ <&tlmm 30 0>,
+ <&pmcobalt_gpios 20 0>,
+ <&tlmm 29 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vdig = <2>;
+ qcom,gpio-vana = <3>;
+ qcom,gpio-req-tbl-num = <0 1 2 3>;
+ qcom,gpio-req-tbl-flags = <1 0 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+ "CAM_RESET0",
+ "CAM_VDIG",
+ "CAM_VANA";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_mmss clk_mclk0_clk_src>,
+ <&clock_mmss clk_mmss_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ eeprom1: qcom,eeprom@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,eeprom";
+ cam_vdig-supply = <&pmcobalt_lvs1>;
+ cam_vio-supply = <&pmcobalt_lvs1>;
+ cam_vana-supply = <&pmicobalt_bob>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-min-voltage = <0 0 3312000>;
+ qcom,cam-vreg-max-voltage = <0 0 3600000>;
+ qcom,cam-vreg-op-mode = <0 0 80000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_active
+ &cam_sensor_rear2_active>;
+ pinctrl-1 = <&cam_sensor_mclk1_suspend
+ &cam_sensor_rear2_suspend>;
+ gpios = <&tlmm 14 0>,
+ <&tlmm 27 0>,
+ <&tlmm 8 0>;
+ qcom,gpio-standby = <1>;
+ qcom,gpio-vana = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK1",
+ "CAM_STANDBY1",
+ "CAM_VANA";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_mmss clk_mclk1_clk_src>,
+ <&clock_mmss clk_mmss_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ eeprom2: qcom,eeprom@2 {
+ cell-index = <2>;
+ reg = <0x2>;
+ compatible = "qcom,eeprom";
+ cam_vio-supply = <&pmcobalt_lvs1>;
+ cam_vana-supply = <&pmcobalt_l22>;
+ cam_vdig-supply = <&pmcobalt_s3>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 2864000 1352000>;
+ qcom,cam-vreg-max-voltage = <0 2864000 1352000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_active
+ &cam_sensor_front_active>;
+ pinctrl-1 = <&cam_sensor_mclk2_active
+ &cam_sensor_front_suspend>;
+ gpios = <&tlmm 15 0>,
+ <&tlmm 9 0>,
+ <&pmcobalt_gpios 9 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vdig = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_RESET2",
+ "CAM_VDIG";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_mmss clk_mclk2_clk_src>,
+ <&clock_mmss clk_mmss_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x0>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <270>;
+ qcom,led-flash-src = <&led_flash0>;
+ qcom,actuator-src = <&actuator0>;
+ qcom,eeprom-src = <&eeprom0>;
+ cam_vio-supply = <&pmcobalt_lvs1>;
+ cam_vana-supply = <&pmicobalt_bob>;
+ cam_vdig-supply = <&pmcobalt_s3>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 3312000 1352000>;
+ qcom,cam-vreg-max-voltage = <0 3600000 1352000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_active
+ &cam_sensor_rear_active>;
+ pinctrl-1 = <&cam_sensor_mclk0_suspend
+ &cam_sensor_rear_suspend>;
+ gpios = <&tlmm 13 0>,
+ <&tlmm 30 0>,
+ <&pmcobalt_gpios 20 0>,
+ <&tlmm 29 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vdig = <2>;
+ qcom,gpio-vana = <3>;
+ qcom,gpio-req-tbl-num = <0 1 2 3>;
+ qcom,gpio-req-tbl-flags = <1 0 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+ "CAM_RESET0",
+ "CAM_VDIG",
+ "CAM_VANA";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_mmss clk_mclk0_clk_src>,
+ <&clock_mmss clk_mmss_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <90>;
+ qcom,eeprom-src = <&eeprom1>;
+ cam_vio-supply = <&pmcobalt_lvs1>;
+ cam_vana-supply = <&pmicobalt_bob>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana";
+ qcom,cam-vreg-min-voltage = <0 3312000>;
+ qcom,cam-vreg-max-voltage = <0 3600000>;
+ qcom,cam-vreg-op-mode = <0 80000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_active
+ &cam_sensor_rear2_active>;
+ pinctrl-1 = <&cam_sensor_mclk1_suspend
+ &cam_sensor_rear2_suspend>;
+ gpios = <&tlmm 14 0>,
+ <&tlmm 27 0>,
+ <&tlmm 8 0>;
+ qcom,gpio-standby = <1>;
+ qcom,gpio-vana = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK1",
+ "CAM_STANDBY1",
+ "CAM_VANA1";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_mmss clk_mclk1_clk_src>,
+ <&clock_mmss clk_mmss_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ qcom,camera@2 {
+ cell-index = <2>;
+ compatible = "qcom,camera";
+ reg = <0x02>;
+ qcom,csiphy-sd-index = <2>;
+ qcom,csid-sd-index = <2>;
+ qcom,mount-angle = <90>;
+ qcom,eeprom-src = <&eeprom2>;
+ qcom,led-flash-src = <&led_flash1>;
+ qcom,actuator-src = <&actuator1>;
+ cam_vio-supply = <&pmcobalt_lvs1>;
+ cam_vana-supply = <&pmcobalt_l22>;
+ cam_vdig-supply = <&pmcobalt_s3>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 2864000 1352000>;
+ qcom,cam-vreg-max-voltage = <0 2864000 1352000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_active
+ &cam_sensor_front_active>;
+ pinctrl-1 = <&cam_sensor_mclk2_suspend
+ &cam_sensor_front_suspend>;
+ gpios = <&tlmm 15 0>,
+ <&tlmm 9 0>,
+ <&pmcobalt_gpios 9 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vdig = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_RESET2",
+ "CAM_VDIG";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_mmss clk_mclk2_clk_src>,
+ <&clock_mmss clk_mmss_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+};
+
+&pmcobalt_gpios {
+ gpio@c800 { /* GPIO 9 - CAMERA SENSOR 2 VDIG */
+ qcom,mode = <1>; /* Output */
+ qcom,pull = <5>; /* No Pull */
+ qcom,vin-sel = <0>; /* VIN1 GPIO_LV */
+ qcom,src-sel = <0>; /* GPIO */
+ qcom,invert = <0>; /* Invert */
+ qcom,master-en = <1>; /* Enable GPIO */
+ status = "ok";
+ };
+
+ gpio@d300 { /* GPIO 20 - CAMERA SENSOR 0 VDIG */
+ qcom,mode = <1>; /* Output */
+ qcom,pull = <5>; /* No Pull */
+ qcom,vin-sel = <1>; /* VIN1 GPIO_MV */
+ qcom,src-sel = <0>; /* GPIO */
+ qcom,invert = <0>; /* Invert */
+ qcom,master-en = <1>; /* Enable GPIO */
+ status = "ok";
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi
index 27e537c9c702..6a0061e206ca 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi
@@ -422,6 +422,8 @@
qcom,msm-bus-vector-dyn-vote;
resets = <&clock_mmss CAMSS_MICRO_BCR>;
reset-names = "micro_iface_reset";
+ qcom,src-clock-rates = <100000000 200000000 576000000
+ 600000000>;
qcom,cpp-fw-payload-info {
qcom,stripe-base = <790>;
qcom,plane-base = <715>;
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-cdp.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-cdp.dtsi
index 9b9b863c1847..ca504a798659 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-cdp.dtsi
@@ -17,11 +17,11 @@
compatible = "qca,wcn3990";
qca,bt-vdd-io-supply = <&pmcobalt_s3>;
qca,bt-vdd-xtal-supply = <&pmcobalt_s5>;
- qca,bt-vdd-core-supply = <&pmcobalt_l7_pin_ctrl>;
- qca,bt-vdd-pa-supply = <&pmcobalt_l17_pin_ctrl>;
- qca,bt-vdd-ldo-supply = <&pmcobalt_l25_pin_ctrl>;
+ qca,bt-vdd-core-supply = <&pmcobalt_l7>;
+ qca,bt-vdd-pa-supply = <&pmcobalt_l17>;
+ qca,bt-vdd-ldo-supply = <&pmcobalt_l25>;
qca,bt-chip-pwd-supply = <&pmicobalt_bob_pin1>;
- clocks = <&clock_gcc clk_rf_clk2>;
+ clocks = <&clock_gcc clk_rf_clk2_pin>;
clock-names = "rf_clk2";
qca,bt-vdd-io-voltage-level = <1352000 1352000>;
@@ -299,7 +299,7 @@
&labibb {
status = "ok";
- qpnp,qpnp-labibb-mode = "lcd";
+ qcom,qpnp-labibb-mode = "lcd";
};
&pmicobalt_wled {
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi
index e140074465ef..8739e8f22549 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi
@@ -77,6 +77,9 @@
qcom,tsens-name = "tsens_tz_sensor12";
+ /* Quirks */
+ qcom,gpu-quirk-lmloadkill-disable;
+
clocks = <&clock_gfx clk_gpucc_gfx3d_clk>,
<&clock_gcc clk_gcc_gpu_cfg_ahb_clk>,
<&clock_gpu clk_gpucc_rbbmtimer_clk>,
@@ -119,6 +122,40 @@
vddcx-supply = <&gdsc_gpu_cx>;
vdd-supply = <&gdsc_gpu_gx>;
+ /* GPU Mempools */
+ qcom,gpu-mempools {
+ #address-cells= <1>;
+ #size-cells = <0>;
+ compatible = "qcom,gpu-mempools";
+
+ /* 4K Page Pool configuration */
+ qcom,gpu-mempool@0 {
+ reg = <0>;
+ qcom,mempool-page-size = <4096>;
+ qcom,mempool-reserved = <2048>;
+ qcom,mempool-allocate;
+ };
+ /* 8K Page Pool configuration */
+ qcom,gpu-mempool@1 {
+ reg = <1>;
+ qcom,mempool-page-size = <8192>;
+ qcom,mempool-reserved = <1024>;
+ qcom,mempool-allocate;
+ };
+ /* 64K Page Pool configuration */
+ qcom,gpu-mempool@2 {
+ reg = <2>;
+ qcom,mempool-page-size = <65536>;
+ qcom,mempool-reserved = <256>;
+ };
+ /* 1M Page Pool configuration */
+ qcom,gpu-mempool@3 {
+ reg = <3>;
+ qcom,mempool-page-size = <1048576>;
+ qcom,mempool-reserved = <32>;
+ };
+ };
+
/* Power levels */
qcom,gpu-pwrlevels {
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon-cdp.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon-cdp.dtsi
index 4822823aa63f..6336726e6b88 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon-cdp.dtsi
@@ -44,9 +44,9 @@
};
&ufsphy1 {
- vdda-phy-supply = <&pmcobalt_l1>;
- vdda-pll-supply = <&pmcobalt_l2>;
- vddp-ref-clk-supply = <&pmcobalt_l26>;
+ vdda-phy-supply = <&pm2falcon_l1>;
+ vdda-pll-supply = <&pmfalcon_l1>;
+ vddp-ref-clk-supply = <&pmfalcon_l1>;
vdda-phy-max-microamp = <51400>;
vdda-pll-max-microamp = <14600>;
vddp-ref-clk-max-microamp = <100>;
@@ -57,12 +57,10 @@
&ufs1 {
vdd-hba-supply = <&gdsc_ufs>;
vdd-hba-fixed-regulator;
- vcc-supply = <&pmcobalt_l20>;
- vccq-supply = <&pmcobalt_l26>;
- vccq2-supply = <&pmcobalt_s4>;
- vcc-max-microamp = <750000>;
- vccq-max-microamp = <560000>;
- vccq2-max-microamp = <750000>;
+ vcc-supply = <&pm2falcon_l4>;
+ vccq2-supply = <&pmfalcon_l8>;
+ vcc-max-microamp = <500000>;
+ vccq2-max-microamp = <600000>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon-mtp.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon-mtp.dtsi
index b77bab712ecf..07e1d665bb0c 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon-mtp.dtsi
@@ -45,9 +45,9 @@
};
&ufsphy1 {
- vdda-phy-supply = <&pmcobalt_l1>;
- vdda-pll-supply = <&pmcobalt_l2>;
- vddp-ref-clk-supply = <&pmcobalt_l26>;
+ vdda-phy-supply = <&pm2falcon_l1>;
+ vdda-pll-supply = <&pmfalcon_l1>;
+ vddp-ref-clk-supply = <&pmfalcon_l1>;
vdda-phy-max-microamp = <51400>;
vdda-pll-max-microamp = <14600>;
vddp-ref-clk-max-microamp = <100>;
@@ -58,12 +58,10 @@
&ufs1 {
vdd-hba-supply = <&gdsc_ufs>;
vdd-hba-fixed-regulator;
- vcc-supply = <&pmcobalt_l20>;
- vccq-supply = <&pmcobalt_l26>;
- vccq2-supply = <&pmcobalt_s4>;
- vcc-max-microamp = <750000>;
- vccq-max-microamp = <560000>;
- vccq2-max-microamp = <750000>;
+ vcc-supply = <&pm2falcon_l4>;
+ vccq2-supply = <&pmfalcon_l8>;
+ vcc-max-microamp = <500000>;
+ vccq2-max-microamp = <600000>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon.dtsi
index 32f616e1dc7a..ffb42576ffd3 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon.dtsi
@@ -3088,3 +3088,48 @@
#include "msmcobalt-mdss-pll.dtsi"
#include "msmcobalt-blsp.dtsi"
#include "msmcobalt-audio.dtsi"
+
+
+/* GPU overrides */
+&msm_gpu {
+ qcom,initial-pwrlevel = <0>;
+
+ qcom,gpu-pwrlevels {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible = "qcom,gpu-pwrlevels";
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <332000000>;
+ qcom,bus-freq = <7>;
+ qcom,bus-min = <6>;
+ qcom,bus-max = <8>;
+ };
+
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <251000000>;
+ qcom,bus-freq = <4>;
+ qcom,bus-min = <3>;
+ qcom,bus-max = <5>;
+ };
+
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <171000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <1>;
+ qcom,bus-max = <4>;
+ };
+
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <27000000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
+ };
+
+};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-interposer-pmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-interposer-pmfalcon.dtsi
index 274281f7c982..ecb30fcc7383 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-interposer-pmfalcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-interposer-pmfalcon.dtsi
@@ -81,18 +81,6 @@
/delete-property/qca,bt-chip-pwd-supply;
};
-&ufsphy1 {
- /delete-property/vdda-phy-supply;
- /delete-property/vdda-pll-supply;
- /delete-property/vddp-ref-clk-supply;
-};
-
-&ufs1 {
- /delete-property/vcc-supply;
- /delete-property/vccq-supply;
- /delete-property/vccq2-supply;
-};
-
&sdhc_2 {
/delete-property/vdd-supply;
/delete-property/vdd-io-supply;
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi
index 9c72ebf4a0bd..75c985189842 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi
@@ -468,9 +468,10 @@
reg = <0xc990000 0xa84>,
<0xc011000 0x910>,
<0x1fcb200 0x050>,
+ <0xc8c2200 0x1a0>,
<0x780000 0x621c>,
<0xc9e1000 0x02c>;
- reg-names = "dp_ctrl", "dp_phy", "tcsr_regs",
+ reg-names = "dp_ctrl", "dp_phy", "tcsr_regs", "dp_mmss_cc",
"qfprom_physical","hdcp_physical";
clocks = <&clock_mmss clk_mmss_mnoc_ahb_clk>,
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi
index 81f53f1512fd..0cd6d0ab1f1d 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi
@@ -18,11 +18,11 @@
compatible = "qca,wcn3990";
qca,bt-vdd-io-supply = <&pmcobalt_s3>;
qca,bt-vdd-xtal-supply = <&pmcobalt_s5>;
- qca,bt-vdd-core-supply = <&pmcobalt_l7_pin_ctrl>;
- qca,bt-vdd-pa-supply = <&pmcobalt_l17_pin_ctrl>;
- qca,bt-vdd-ldo-supply = <&pmcobalt_l25_pin_ctrl>;
+ qca,bt-vdd-core-supply = <&pmcobalt_l7>;
+ qca,bt-vdd-pa-supply = <&pmcobalt_l17>;
+ qca,bt-vdd-ldo-supply = <&pmcobalt_l25>;
qca,bt-chip-pwd-supply = <&pmicobalt_bob_pin1>;
- clocks = <&clock_gcc clk_rf_clk2>;
+ clocks = <&clock_gcc clk_rf_clk2_pin>;
clock-names = "rf_clk2";
qca,bt-vdd-io-voltage-level = <1352000 1352000>;
@@ -269,7 +269,7 @@
batt_i@3 {
reg = <3>;
qcom,channel = <3>;
- qcom,scale = <20000000>;
+ qcom,scale = <(-20000000)>;
};
batt_v@4 {
@@ -362,7 +362,7 @@
&labibb {
status = "ok";
- qpnp,qpnp-labibb-mode = "lcd";
+ qcom,qpnp-labibb-mode = "lcd";
};
&pmicobalt_wled {
@@ -469,6 +469,10 @@
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
};
+&mem_client_3_size {
+ qcom,peripheral-size = <0x500000>;
+};
+
&pmicobalt_haptics {
status = "okay";
};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dts b/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dts
index b5a94de9aab7..88a5e945436c 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dts
+++ b/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dts
@@ -15,7 +15,6 @@
#include "msmcobalt.dtsi"
#include "msmcobalt-qrd-skuk.dtsi"
-#include "msmcobalt-camera-sensor-skuk.dtsi"
/ {
model = "Qualcomm Technologies, Inc. MSM COBALT SKUK";
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dtsi
index 58471f6d0fd1..15756d13d2e0 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dtsi
@@ -13,6 +13,7 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include "msmcobalt-pinctrl.dtsi"
#include "msmcobalt-audio.dtsi"
+#include "msmcobalt-camera-sensor-skuk.dtsi"
&blsp1_uart3_hs {
status = "ok";
@@ -184,7 +185,7 @@
&labibb {
status = "ok";
- qpnp,qpnp-labibb-mode = "lcd";
+ qcom,qpnp-labibb-mode = "lcd";
};
&dsi_dual_jdi_a407_cmd {
@@ -193,3 +194,19 @@
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
};
+
+/{
+ qrd_batterydata: qcom,battery-data {
+ qcom,batt-id-range-pct = <15>;
+
+ #include "batterydata-qrd-skuk-4v4-3000mah.dtsi"
+ };
+};
+
+&pmicobalt_fg {
+ qcom,battery-data = <&qrd_batterydata>;
+};
+
+&pmicobalt_haptics {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-qrd-vr1.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-qrd-vr1.dtsi
index f0607ac3a34a..71fd5cc1383f 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-qrd-vr1.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-qrd-vr1.dtsi
@@ -12,6 +12,7 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include "msmcobalt-pinctrl.dtsi"
+#include "msmcobalt-camera-sensor-qrd-vr1.dtsi"
&blsp1_uart3_hs {
status = "ok";
@@ -127,3 +128,19 @@
qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrLeft";
};
};
+
+/{
+ qrd_batterydata: qcom,battery-data {
+ qcom,batt-id-range-pct = <15>;
+
+ #include "batterydata-qrd-skuk-4v4-3000mah.dtsi"
+ };
+};
+
+&pmicobalt_fg {
+ qcom,battery-data = <&qrd_batterydata>;
+};
+
+&pmicobalt_haptics {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-qrd.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-qrd.dtsi
index 682ea8a260ef..6483453ec5fa 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-qrd.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-qrd.dtsi
@@ -260,7 +260,7 @@
&labibb {
status = "ok";
- qpnp,qpnp-labibb-mode = "lcd";
+ qcom,qpnp-labibb-mode = "lcd";
};
&pmicobalt_wled {
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi
index 1ba5905bcc36..32cf1663cf43 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi
@@ -1101,6 +1101,8 @@
qcom,cpr-aging-ref-corner = <6>;
qcom,cpr-aging-ro-scaling-factor = <2950>;
qcom,allow-aging-voltage-adjustment = <0>;
+ qcom,allow-aging-open-loop-voltage-adjustment =
+ <1>;
};
};
};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi
index fcc4d6d8ee2d..a81287c36266 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi
@@ -116,5 +116,76 @@
0 256000000 0>;
status = "ok";
};
+
+ qcom,cpp@ca04000 {
+ cell-index = <0>;
+ compatible = "qcom,cpp";
+ reg = <0xca04000 0x100>,
+ <0xca80000 0x3000>,
+ <0xca18000 0x3000>,
+ <0xc8c36d4 0x4>;
+ reg-names = "cpp", "cpp_vbif", "cpp_hw", "camss_cpp";
+ interrupts = <0 294 0>;
+ interrupt-names = "cpp";
+ smmu-vdd-supply = <&gdsc_bimc_smmu>;
+ camss-vdd-supply = <&gdsc_camss_top>;
+ vdd-supply = <&gdsc_cpp>;
+ qcom,vdd-names = "smmu-vdd", "camss-vdd", "vdd";
+ clocks = <&clock_gcc clk_mmssnoc_axi_clk>,
+ <&clock_mmss clk_mmss_mnoc_ahb_clk>,
+ <&clock_mmss clk_mmss_camss_ahb_clk>,
+ <&clock_mmss clk_mmss_camss_top_ahb_clk>,
+ <&clock_mmss clk_cpp_clk_src>,
+ <&clock_mmss clk_mmss_camss_cpp_clk>,
+ <&clock_mmss clk_mmss_camss_cpp_ahb_clk>,
+ <&clock_mmss clk_mmss_camss_cpp_axi_clk>,
+ <&clock_mmss clk_mmss_camss_micro_ahb_clk>,
+ <&clock_mmss clk_mmss_bimc_smmu_axi_clk>,
+ <&clock_mmss clk_mmss_camss_cpp_vbif_ahb_clk>;
+ clock-names = "mmssnoc_axi_clk",
+ "mnoc_ahb_clk",
+ "camss_ahb_clk", "camss_top_ahb_clk",
+ "cpp_src_clk",
+ "cpp_core_clk", "camss_cpp_ahb_clk",
+ "camss_cpp_axi_clk", "micro_iface_clk",
+ "mmss_smmu_axi_clk", "cpp_vbif_ahb_clk";
+ qcom,clock-rates = <0 0 0 0 200000000 200000000 0 0 0 0 0>;
+ qcom,min-clock-rate = <200000000>;
+ qcom,bus-master = <1>;
+ qcom,vbif-qos-setting = <0x20 0x10000000>,
+ <0x24 0x10000000>,
+ <0x28 0x10000000>,
+ <0x2C 0x10000000>;
+ status = "ok";
+ qcom,msm-bus,name = "msm_camera_cpp";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <106 512 0 0>,
+ <106 512 0 0>;
+ qcom,msm-bus-vector-dyn-vote;
+ resets = <&clock_mmss CAMSS_MICRO_BCR>;
+ reset-names = "micro_iface_reset";
+ qcom,src-clock-rates = <100000000 200000000 384000000 404000000
+ 480000000 576000000 600000000>;
+ qcom,cpp-fw-payload-info {
+ qcom,stripe-base = <790>;
+ qcom,plane-base = <715>;
+ qcom,stripe-size = <63>;
+ qcom,plane-size = <25>;
+ qcom,fe-ptr-off = <11>;
+ qcom,we-ptr-off = <23>;
+ qcom,ref-fe-ptr-off = <17>;
+ qcom,ref-we-ptr-off = <36>;
+ qcom,we-meta-ptr-off = <42>;
+ qcom,fe-mmu-pf-ptr-off = <7>;
+ qcom,ref-fe-mmu-pf-ptr-off = <10>;
+ qcom,we-mmu-pf-ptr-off = <13>;
+ qcom,dup-we-mmu-pf-ptr-off = <18>;
+ qcom,ref-we-mmu-pf-ptr-off = <23>;
+ qcom,set-group-buffer-len = <135>;
+ qcom,dup-frame-indicator-off = <70>;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-interposer-msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-v2-interposer-msmfalcon.dtsi
index 02cc86212301..46ed1f219970 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-v2-interposer-msmfalcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-v2-interposer-msmfalcon.dtsi
@@ -750,7 +750,7 @@
&msm_gpu {
/* Updated chip ID */
qcom,chipid = <0x05040001>;
- qcom,initial-pwrlevel = <5>;
+ qcom,initial-pwrlevel = <0>;
qcom,gpu-pwrlevels {
#address-cells = <1>;
@@ -760,61 +760,29 @@
qcom,gpu-pwrlevel@0 {
reg = <0>;
- qcom,gpu-freq = <670000000>;
- qcom,bus-freq = <12>;
- qcom,bus-min = <11>;
- qcom,bus-max = <12>;
- };
-
- qcom,gpu-pwrlevel@1 {
- reg = <1>;
- qcom,gpu-freq = <596000000>;
- qcom,bus-freq = <11>;
- qcom,bus-min = <9>;
- qcom,bus-max = <12>;
- };
-
- qcom,gpu-pwrlevel@2 {
- reg = <2>;
- qcom,gpu-freq = <515000000>;
- qcom,bus-freq = <11>;
- qcom,bus-min = <9>;
- qcom,bus-max = <12>;
- };
-
- qcom,gpu-pwrlevel@3 {
- reg = <3>;
- qcom,gpu-freq = <414000000>;
- qcom,bus-freq = <9>;
- qcom,bus-min = <8>;
- qcom,bus-max = <11>;
- };
-
- qcom,gpu-pwrlevel@4 {
- reg = <4>;
qcom,gpu-freq = <342000000>;
qcom,bus-freq = <8>;
qcom,bus-min = <5>;
qcom,bus-max = <9>;
};
- qcom,gpu-pwrlevel@5 {
- reg = <5>;
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
qcom,gpu-freq = <257000000>;
qcom,bus-freq = <5>;
qcom,bus-min = <3>;
qcom,bus-max = <8>;
};
- qcom,gpu-pwrlevel@6 {
- reg = <6>;
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
qcom,gpu-freq = <180000000>;
qcom,bus-freq = <3>;
qcom,bus-min = <1>;
qcom,bus-max = <5>;
};
- qcom,gpu-pwrlevel@7 {
- reg = <7>;
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
qcom,gpu-freq = <27000000>;
qcom,bus-freq = <0>;
qcom,bus-min = <0>;
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-qrd-skuk.dts b/arch/arm/boot/dts/qcom/msmcobalt-v2-qrd-skuk.dts
index 78e810b816c9..581e9fef1aeb 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-v2-qrd-skuk.dts
+++ b/arch/arm/boot/dts/qcom/msmcobalt-v2-qrd-skuk.dts
@@ -19,5 +19,5 @@
/ {
model = "Qualcomm Technologies, Inc. MSM COBALT V2 SKUK";
compatible = "qcom,msmcobalt-qrd", "qcom,msmcobalt", "qcom,qrd";
- qcom,board-id = <0x01000b 0x80>;
+ qcom,board-id = <0x01000b 0x10>;
};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dts b/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dts
index 69a5419503ac..e5ad123f52a7 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dts
+++ b/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dts
@@ -21,3 +21,194 @@
compatible = "qcom,msmcobalt-qrd", "qcom,msmcobalt", "qcom,qrd";
qcom,board-id = <0x03000b 0x80>;
};
+
+&slim_aud {
+ tasha_codec {
+ /delete-property/cdc-vdd-buck-supply;
+ /delete-property/cdc-buck-sido-supply;
+ /delete-property/cdc-vdd-tx-h-supply;
+ /delete-property/cdc-vdd-rx-h-supply;
+ /delete-property/cdc-vddpx-1-supply;
+ };
+
+ tavil_codec {
+ /delete-property/cdc-vdd-buck-supply;
+ /delete-property/cdc-buck-sido-supply;
+ /delete-property/cdc-vdd-tx-h-supply;
+ /delete-property/cdc-vdd-rx-h-supply;
+ /delete-property/cdc-vddpx-1-supply;
+ };
+};
+
+&clock_gcc {
+ /delete-property/vdd_dig-supply;
+ /delete-property/vdd_dig_ao-supply;
+};
+
+&clock_mmss {
+ /delete-property/vdd_dig-supply;
+ /delete-property/vdd_mmsscc_mx-supply;
+};
+
+&clock_gpu {
+ /delete-property/vdd_dig-supply;
+};
+
+&clock_gfx {
+ /delete-property/vdd_mx-supply;
+ /delete-property/vdd_gpu_mx-supply;
+};
+
+&pcie0 {
+ /delete-property/vreg-1.8-supply;
+ /delete-property/vreg-0.9-supply;
+ /delete-property/vreg-cx-supply;
+};
+
+&qusb_phy0 {
+ /delete-property/vdd-supply;
+ /delete-property/vdda18-supply;
+ /delete-property/vdda33-supply;
+};
+
+&ssphy {
+ /delete-property/vdd-supply;
+ /delete-property/core-supply;
+};
+
+&usb3 {
+ /delete-property/extcon;
+};
+
+&mdss_dsi {
+ /delete-property/vdda-1p2-supply;
+ /delete-property/vdda-0p9-supply;
+};
+
+&mdss_dsi0 {
+ /delete-property/wqhd-vddio-supply;
+ /delete-property/lab-supply;
+ /delete-property/ibb-supply;
+};
+
+&mdss_dsi1 {
+ /delete-property/wqhd-vddio-supply;
+ /delete-property/lab-supply;
+ /delete-property/ibb-supply;
+};
+
+&mdss_hdmi_pll {
+ /delete-property/vdda-pll-supply;
+ /delete-property/vdda-phy-supply;
+};
+
+&mdss_dp_ctrl {
+ /delete-property/vdda-1p2-supply;
+ /delete-property/vdda-0p9-supply;
+ /delete-property/qcom,dp-usbpd-detection;
+};
+
+&apc0_cpr {
+ /* disable aging and closed-loop */
+ /delete-property/vdd-supply;
+ /delete-property/qcom,cpr-enable;
+ /delete-property/qcom,cpr-hw-closed-loop;
+ /delete-property/qcom,cpr-aging-ref-voltage;
+};
+
+&apc0_pwrcl_vreg {
+ /delete-property/qcom,cpr-aging-max-voltage-adjustment;
+ /delete-property/qcom,cpr-aging-ref-corner;
+ /delete-property/qcom,cpr-aging-ro-scaling-factor;
+ /delete-property/qcom,allow-aging-voltage-adjustment;
+ /delete-property/qcom,allow-aging-open-loop-voltage-adjustment;
+};
+
+&apc1_cpr {
+ /* disable aging and closed-loop */
+ /delete-property/vdd-supply;
+ /delete-property/qcom,cpr-enable;
+ /delete-property/qcom,cpr-hw-closed-loop;
+ /delete-property/qcom,cpr-aging-ref-voltage;
+};
+
+&apc1_perfcl_vreg {
+ /delete-property/qcom,cpr-aging-max-voltage-adjustment;
+ /delete-property/qcom,cpr-aging-ref-corner;
+ /delete-property/qcom,cpr-aging-ro-scaling-factor;
+ /delete-property/qcom,allow-aging-voltage-adjustment;
+ /delete-property/qcom,allow-aging-open-loop-voltage-adjustment;
+};
+
+&gfx_cpr {
+ reg = <0x05061000 0x4000>,
+ <0x00784000 0x1000>;
+ reg-names = "cpr_ctrl", "fuse_base";
+
+ /* disable aging and closed-loop */
+ /delete-property/vdd-supply;
+ /delete-property/qcom,cpr-enable;
+ /delete-property/qcom,cpr-aging-ref-voltage;
+ /delete-property/qcom,cpr-aging-allowed-reg-mask;
+ /delete-property/qcom,cpr-aging-allowed-reg-value;
+};
+
+&gfx_vreg {
+ /delete-property/qcom,cpr-aging-max-voltage-adjustment;
+ /delete-property/qcom,cpr-aging-ref-corner;
+ /delete-property/qcom,cpr-aging-ro-scaling-factor;
+ /delete-property/qcom,allow-aging-voltage-adjustment;
+ /delete-property/qcom,allow-aging-open-loop-voltage-adjustment;
+};
+
+&clock_audio {
+ /delete-property/qcom,audio-ref-clk-gpio;
+};
+
+&soc {
+ /delete-node/qcom,csid@ca30000;
+ /delete-node/qcom,csid@ca30400;
+ /delete-node/qcom,csid@ca30800;
+ /delete-node/qcom,csid@ca30c00;
+
+ /delete-node/qcom,lpass@17300000;
+ /delete-node/qcom,mss@4080000;
+ /delete-node/qcom,spss@1d00000;
+ /delete-node/qcom,bcl;
+ /delete-node/qcom,msm-thermal;
+ /delete-node/qcom,ssc@5c00000;
+ /delete-node/qcom,icnss@18800000;
+ /delete-node/qcom,wil6210;
+ /delete-node/qcom,rpm-smd;
+ /delete-node/qcom,spmi@800f000;
+
+
+ rpm_bus: qcom,rpm-smd {
+ compatible = "qcom,rpm-glink";
+ qcom,glink-edge = "rpm";
+ rpm-channel-name = "rpm_requests";
+ };
+
+ spmi_bus: qcom,spmi@800f000 {
+ compatible = "qcom,spmi-pmic-arb";
+ reg = <0x800f000 0x1000>,
+ <0x8400000 0x1000000>,
+ <0x9400000 0x1000000>,
+ <0xa400000 0x220000>,
+ <0x800a000 0x3000>;
+ reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
+ interrupt-names = "periph_irq";
+ interrupts = <GIC_SPI 326 IRQ_TYPE_NONE>;
+ qcom,ee = <0>;
+ qcom,channel = <0>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+ interrupt-controller;
+ #interrupt-cells = <4>;
+ cell-index = <0>;
+ };
+};
+
+#include "msm-pmfalcon.dtsi"
+#include "msm-pm2falcon.dtsi"
+#include "msmfalcon-regulator.dtsi"
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dtsi
index 6e639ff9e0bc..b257281466a9 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dtsi
@@ -18,3 +18,68 @@
pinctrl-names = "default";
pinctrl-0 = <&uart_console_active>;
};
+
+&ufsphy1 {
+ vdda-phy-max-microamp = <51400>;
+ vdda-pll-max-microamp = <14600>;
+ vddp-ref-clk-max-microamp = <100>;
+ vddp-ref-clk-always-on;
+ status = "ok";
+};
+
+&ufs1 {
+ vdd-hba-supply = <&gdsc_ufs>;
+ vdd-hba-fixed-regulator;
+ vcc-max-microamp = <750000>;
+ vccq-max-microamp = <560000>;
+ vccq2-max-microamp = <750000>;
+ status = "ok";
+};
+
+&ufs_ice {
+ status = "ok";
+};
+
+&sdc2_cd_on {
+ mux {
+ pins = "gpio54";
+ };
+
+ config {
+ pins = "gpio54";
+ /delete-property/ bias-pull-up;
+ bias-disable;
+ };
+};
+
+&sdc2_cd_off {
+ mux {
+ pins = "gpio54";
+ };
+
+ config {
+ pins = "gpio54";
+ /delete-property/ bias-pull-up;
+ bias-disable;
+ };
+};
+
+&sdhc_2 {
+ qcom,vdd-voltage-level = <2950000 2960000>;
+ qcom,vdd-current-level = <200 800000>;
+
+ qcom,vdd-io-voltage-level = <1808000 2960000>;
+ qcom,vdd-io-current-level = <200 22000>;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+
+ qcom,clk-rates = <400000 20000000 25000000
+ 50000000 100000000 200000000>;
+ qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+
+ cd-gpios = <&tlmm 54 0x0>;
+
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-v2.dtsi
index a0d1f1fa11af..93b586df5640 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-v2.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-v2.dtsi
@@ -205,6 +205,24 @@
};
};
+&devfreq_memlat_0 {
+ qcom,core-dev-table =
+ < 595200 3143 >,
+ < 1324800 4173 >,
+ < 1555200 5859 >,
+ < 1747200 5859 >,
+ < 1900800 7759 >;
+};
+
+&devfreq_memlat_4 {
+ qcom,core-dev-table =
+ < 576000 3143 >,
+ < 1132800 4173 >,
+ < 1344000 5859 >,
+ < 1728000 7759 >,
+ < 1958400 11863 >,
+ < 2208000 13763 >;
+};
&clock_gcc {
compatible = "qcom,gcc-cobalt-v2";
};
@@ -227,7 +245,8 @@
< 414000000 4 RPM_SMD_REGULATOR_LEVEL_SVS >,
< 515000000 5 RPM_SMD_REGULATOR_LEVEL_NOM >,
< 596000000 6 RPM_SMD_REGULATOR_LEVEL_NOM >,
- < 670000000 7 RPM_SMD_REGULATOR_LEVEL_TURBO >;
+ < 670000000 7 RPM_SMD_REGULATOR_LEVEL_TURBO >,
+ < 710000000 8 RPM_SMD_REGULATOR_LEVEL_TURBO >;
qcom,gfxfreq-mx-speedbin0 =
< 0 0 >,
< 180000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
@@ -236,7 +255,8 @@
< 414000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
< 515000000 RPM_SMD_REGULATOR_LEVEL_NOM >,
< 596000000 RPM_SMD_REGULATOR_LEVEL_NOM >,
- < 670000000 RPM_SMD_REGULATOR_LEVEL_TURBO >;
+ < 670000000 RPM_SMD_REGULATOR_LEVEL_TURBO >,
+ < 710000000 RPM_SMD_REGULATOR_LEVEL_TURBO >;
};
&mdss_mdp {
@@ -438,43 +458,43 @@
qcom,cpr-open-loop-voltage-fuse-adjustment =
/* Speed bin 0 */
- <40000 24000 0 30000>,
- <40000 24000 0 30000>,
- <40000 24000 0 30000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
+ <40000 24000 0 30000>,
+ <40000 24000 0 30000>,
+ <40000 24000 0 30000>,
+ <40000 24000 0 30000>,
+ <25000 9000 (-15000) 15000>,
+ <25000 9000 (-15000) 15000>,
+ <25000 9000 (-15000) 15000>,
+ <25000 9000 (-15000) 15000>,
/* Speed bin 1 */
- <40000 24000 0 30000>,
- <40000 24000 0 30000>,
- <40000 24000 0 30000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>;
+ <40000 24000 0 30000>,
+ <40000 24000 0 30000>,
+ <40000 24000 0 30000>,
+ <40000 24000 0 30000>,
+ <25000 9000 (-15000) 15000>,
+ <25000 9000 (-15000) 15000>,
+ <25000 9000 (-15000) 15000>,
+ <25000 9000 (-15000) 15000>;
qcom,cpr-closed-loop-voltage-fuse-adjustment =
/* Speed bin 0 */
- <20000 26000 0 30000>,
- <20000 26000 0 30000>,
- <20000 26000 0 30000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>,
+ <20000 26000 0 30000>,
+ <20000 26000 0 30000>,
+ <20000 26000 0 30000>,
+ <20000 26000 0 30000>,
+ < 5000 11000 (-15000) 15000>,
+ < 5000 11000 (-15000) 15000>,
+ < 5000 11000 (-15000) 15000>,
+ < 5000 11000 (-15000) 15000>,
/* Speed bin 1 */
- <20000 26000 0 30000>,
- <20000 26000 0 30000>,
- <20000 26000 0 30000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>,
- <5000 11000 (-15000) 15000>;
+ <20000 26000 0 30000>,
+ <20000 26000 0 30000>,
+ <20000 26000 0 30000>,
+ <20000 26000 0 30000>,
+ < 5000 11000 (-15000) 15000>,
+ < 5000 11000 (-15000) 15000>,
+ < 5000 11000 (-15000) 15000>,
+ < 5000 11000 (-15000) 15000>;
qcom,allow-voltage-interpolation;
qcom,allow-quotient-interpolation;
@@ -483,8 +503,8 @@
qcom,cpr-aging-ref-corner = <22 22>;
qcom,cpr-aging-ro-scaling-factor = <1620>;
qcom,allow-aging-voltage-adjustment =
- <0 0 0 1 1 1 1 1>,
- <0 0 0 1 1 1 1 1>;
+ <0 0 0 0 1 1 1 1>,
+ <0 0 0 0 1 1 1 1>;
};
&apc1_cpr {
@@ -601,19 +621,19 @@
qcom,cpr-open-loop-voltage-fuse-adjustment =
/* Speed bin 0 */
- <8000 0 0 52000>,
- <8000 0 0 52000>,
- <8000 0 0 52000>,
- <(-7000) (-15000) (-15000) 37000>,
+ < 8000 0 0 52000>,
+ < 8000 0 0 52000>,
+ < 8000 0 0 52000>,
+ < 8000 0 0 52000>,
<(-7000) (-15000) (-15000) 37000>,
<(-7000) (-15000) (-15000) 37000>,
<(-7000) (-15000) (-15000) 37000>,
<(-7000) (-15000) (-15000) 37000>,
/* Speed bin 1 */
- <8000 0 0 52000>,
- <8000 0 0 52000>,
- <8000 0 0 52000>,
- <(-7000) (-15000) (-15000) 37000>,
+ < 8000 0 0 52000>,
+ < 8000 0 0 52000>,
+ < 8000 0 0 52000>,
+ < 8000 0 0 52000>,
<(-7000) (-15000) (-15000) 37000>,
<(-7000) (-15000) (-15000) 37000>,
<(-7000) (-15000) (-15000) 37000>,
@@ -621,19 +641,19 @@
qcom,cpr-closed-loop-voltage-fuse-adjustment =
/* Speed bin 0 */
- <0 0 0 50000>,
- <0 0 0 50000>,
- <0 0 0 50000>,
- <(-15000) (-15000) (-15000) 35000>,
+ < 0 0 0 50000>,
+ < 0 0 0 50000>,
+ < 0 0 0 50000>,
+ < 0 0 0 50000>,
<(-15000) (-15000) (-15000) 35000>,
<(-15000) (-15000) (-15000) 35000>,
<(-15000) (-15000) (-15000) 35000>,
<(-15000) (-15000) (-15000) 35000>,
/* Speed bin 1 */
- <0 0 0 50000>,
- <0 0 0 50000>,
- <0 0 0 50000>,
- <(-15000) (-15000) (-15000) 35000>,
+ < 0 0 0 50000>,
+ < 0 0 0 50000>,
+ < 0 0 0 50000>,
+ < 0 0 0 50000>,
<(-15000) (-15000) (-15000) 35000>,
<(-15000) (-15000) (-15000) 35000>,
<(-15000) (-15000) (-15000) 35000>,
@@ -646,8 +666,8 @@
qcom,cpr-aging-ref-corner = <30 26>;
qcom,cpr-aging-ro-scaling-factor = <1700>;
qcom,allow-aging-voltage-adjustment =
- <0 0 0 1 1 1 1 1>,
- <0 0 0 1 1 1 1 1>;
+ <0 0 0 0 1 1 1 1>,
+ <0 0 0 0 1 1 1 1>;
};
&pm8005_s1 {
@@ -671,14 +691,14 @@
qcom,cpr-corner-fmax-map = <1 3 5 8>;
qcom,cpr-voltage-ceiling =
- <656000 716000 772000 880000 908000 948000 1016000 1088000>,
- <660000 724000 772000 832000 916000 968000 1024000 1024000>,
- <660000 724000 772000 832000 916000 968000 1024000 1024000>,
- <660000 724000 772000 832000 916000 968000 1024000 1024000>,
- <660000 724000 772000 832000 916000 968000 1024000 1024000>,
- <660000 724000 772000 832000 916000 968000 1024000 1024000>,
- <660000 724000 772000 832000 916000 968000 1024000 1024000>,
- <660000 724000 772000 832000 916000 968000 1024000 1024000>;
+ <716000 716000 772000 880000 908000 948000 1016000 1088000>,
+ <724000 724000 772000 832000 916000 968000 1024000 1024000>,
+ <724000 724000 772000 832000 916000 968000 1024000 1024000>,
+ <724000 724000 772000 832000 916000 968000 1024000 1024000>,
+ <724000 724000 772000 832000 916000 968000 1024000 1024000>,
+ <724000 724000 772000 832000 916000 968000 1024000 1024000>,
+ <724000 724000 772000 832000 916000 968000 1024000 1024000>,
+ <724000 724000 772000 832000 916000 968000 1024000 1024000>;
qcom,cpr-voltage-floor =
<516000 516000 532000 584000 632000 672000 712000 756000>;
@@ -726,38 +746,38 @@
0 0 2168 0 2209 1849 1997 0>;
qcom,cpr-open-loop-voltage-fuse-adjustment =
- < 100000 0 0 0>,
- < 100000 0 0 0>,
- < 85000 (-15000) (-15000) (-15000)>,
- < 85000 (-15000) (-15000) (-15000)>,
- < 85000 (-15000) (-15000) (-15000)>,
- < 85000 (-15000) (-15000) (-15000)>,
- < 85000 (-15000) (-15000) (-15000)>,
- < 85000 (-15000) (-15000) (-15000)>;
+ < 60000 0 0 0>,
+ < 60000 0 0 0>,
+ < 60000 0 0 0>,
+ < 45000 (-15000) (-15000) (-15000)>,
+ < 45000 (-15000) (-15000) (-15000)>,
+ < 45000 (-15000) (-15000) (-15000)>,
+ < 45000 (-15000) (-15000) (-15000)>,
+ < 45000 (-15000) (-15000) (-15000)>;
qcom,cpr-closed-loop-voltage-adjustment =
- < 96000 18000 4000 0
- 0 13000 9000 0>,
- < 96000 18000 4000 0
- 0 13000 9000 0>,
- < 81000 3000 (-11000) (-15000)
- (-15000) (-2000) (-6000) (-15000)>,
- < 81000 3000 (-11000) (-15000)
- (-15000) (-2000) (-6000) (-15000)>,
- < 81000 3000 (-11000) (-15000)
- (-15000) (-2000) (-6000) (-15000)>,
- < 81000 3000 (-11000) (-15000)
- (-15000) (-2000) (-6000) (-15000)>,
- < 81000 3000 (-11000) (-15000)
- (-15000) (-2000) (-6000) (-15000)>,
- < 81000 3000 (-11000) (-15000)
- (-15000) (-2000) (-6000) (-15000)>;
+ < 90000 38000 28000 8000
+ 0 29000 11000 0>,
+ < 90000 38000 28000 8000
+ 0 29000 11000 0>,
+ < 90000 38000 28000 8000
+ 0 29000 11000 0>,
+ < 75000 23000 13000 (-7000)
+ (-15000) 14000 (-4000) (-15000)>,
+ < 75000 23000 13000 (-7000)
+ (-15000) 14000 (-4000) (-15000)>,
+ < 75000 23000 13000 (-7000)
+ (-15000) 14000 (-4000) (-15000)>,
+ < 75000 23000 13000 (-7000)
+ (-15000) 14000 (-4000) (-15000)>,
+ < 75000 23000 13000 (-7000)
+ (-15000) 14000 (-4000) (-15000)>;
qcom,cpr-floor-to-ceiling-max-range =
<50000 50000 50000 50000 50000 50000 70000 70000>;
qcom,cpr-fused-closed-loop-voltage-adjustment-map =
- <0 0 1 2 3 0 0 4>;
+ <0 0 0 0 1 2 3 4>;
qcom,allow-voltage-interpolation;
qcom,cpr-scaled-open-loop-voltage-as-ceiling;
@@ -765,7 +785,7 @@
qcom,cpr-aging-max-voltage-adjustment = <15000>;
qcom,cpr-aging-ref-corner = <8>;
qcom,cpr-aging-ro-scaling-factor = <1620>;
- qcom,allow-aging-voltage-adjustment = <0 0 1 1 1 1 1 1>;
+ qcom,allow-aging-voltage-adjustment = <0 0 0 1 1 1 1 1>;
};
&qusb_phy0 {
@@ -909,13 +929,6 @@
qcom,gpu-pwrlevel@6 {
reg = <6>;
- qcom,gpu-freq = <180000000>;
- qcom,bus-freq = <3>;
- qcom,bus-min = <1>;
- qcom,bus-max = <5>;
- };
- qcom,gpu-pwrlevel@7 {
- reg = <7>;
qcom,gpu-freq = <27000000>;
qcom,bus-freq = <0>;
qcom,bus-min = <0>;
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-vidc.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-vidc.dtsi
index f17be7570742..a8655c2e88a0 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-vidc.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-vidc.dtsi
@@ -25,6 +25,7 @@
qcom,firmware-name = "venus";
qcom,never-unload-fw;
qcom,sw-power-collapse;
+ qcom,max-secure-instances = <5>;
qcom,debug-timeout;
qcom,reg-presets =
<0x80124 0x00000003>,
diff --git a/arch/arm/boot/dts/qcom/msmcobalt.dtsi b/arch/arm/boot/dts/qcom/msmcobalt.dtsi
index cbddad0bbcb0..cee85ff63ca8 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt.dtsi
@@ -611,7 +611,7 @@
< 13763 /* 1804 MHz */ >;
};
- qcom,arm-memlat-mon-0 {
+ devfreq_memlat_0: qcom,arm-memlat-mon-0 {
compatible = "qcom,arm-memlat-mon";
qcom,cpulist = <&CPU0 &CPU1 &CPU2 &CPU3>;
qcom,target-dev = <&memlat_cpu0>;
@@ -622,7 +622,7 @@
< 1881600 5859 >;
};
- qcom,arm-memlat-mon-4 {
+ devfreq_memlat_4: qcom,arm-memlat-mon-4 {
compatible = "qcom,arm-memlat-mon";
qcom,cpulist = <&CPU4 &CPU5 &CPU6 &CPU7>;
qcom,target-dev = <&memlat_cpu4>;
@@ -1441,180 +1441,6 @@
};
};
- pcie0: qcom,pcie@01c00000 {
- compatible = "qcom,pci-msm";
- cell-index = <0>;
-
- reg = <0x1c00000 0x2000>,
- <0x1c06000 0x1000>,
- <0x1b000000 0xf1d>,
- <0x1b000f20 0xa8>,
- <0x1b100000 0x100000>,
- <0x1b200000 0x100000>,
- <0x1b300000 0xd00000>;
-
- reg-names = "parf", "phy", "dm_core", "elbi",
- "conf", "io", "bars";
-
- #address-cells = <3>;
- #size-cells = <2>;
- ranges = <0x01000000 0x0 0x1b200000 0x1b200000 0x0 0x100000>,
- <0x02000000 0x0 0x1b300000 0x1b300000 0x0 0xd00000>;
- interrupt-parent = <&pcie0>;
- interrupts = <0 1 2 3 4 5>;
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 0xffffffff>;
- interrupt-map = <0 0 0 0 &intc 0 0 405 0
- 0 0 0 1 &intc 0 0 135 0
- 0 0 0 2 &intc 0 0 136 0
- 0 0 0 3 &intc 0 0 138 0
- 0 0 0 4 &intc 0 0 139 0
- 0 0 0 5 &intc 0 0 278 0>;
-
- interrupt-names = "int_msi", "int_a", "int_b", "int_c",
- "int_d", "int_global_int";
-
- qcom,phy-sequence = <0x804 0x01 0x00
- 0x034 0x14 0x00
- 0x138 0x30 0x00
- 0x048 0x0f 0x00
- 0x15c 0x06 0x00
- 0x090 0x01 0x00
- 0x088 0x20 0x00
- 0x0f0 0x00 0x00
- 0x0f8 0x01 0x00
- 0x0f4 0xc9 0x00
- 0x11c 0xff 0x00
- 0x120 0x3f 0x00
- 0x164 0x01 0x00
- 0x154 0x00 0x00
- 0x148 0x0a 0x00
- 0x05C 0x19 0x00
- 0x038 0x90 0x00
- 0x0b0 0x82 0x00
- 0x0c0 0x03 0x00
- 0x0bc 0x55 0x00
- 0x0b8 0x55 0x00
- 0x0a0 0x00 0x00
- 0x09c 0x0d 0x00
- 0x098 0x04 0x00
- 0x13c 0x00 0x00
- 0x060 0x08 0x00
- 0x068 0x16 0x00
- 0x070 0x34 0x00
- 0x15c 0x06 0x00
- 0x138 0x33 0x00
- 0x03c 0x02 0x00
- 0x040 0x0e 0x00
- 0x080 0x04 0x00
- 0x0dc 0x00 0x00
- 0x0d8 0x3f 0x00
- 0x00c 0x09 0x00
- 0x010 0x01 0x00
- 0x01c 0x40 0x00
- 0x020 0x01 0x00
- 0x014 0x02 0x00
- 0x018 0x00 0x00
- 0x024 0x7e 0x00
- 0x028 0x15 0x00
- 0x244 0x02 0x00
- 0x2a4 0x12 0x00
- 0x260 0x10 0x00
- 0x28c 0x06 0x00
- 0x504 0x03 0x00
- 0x500 0x1c 0x00
- 0x50c 0x14 0x00
- 0x4d4 0x0a 0x00
- 0x4d8 0x04 0x00
- 0x4dc 0x1a 0x00
- 0x434 0x4b 0x00
- 0x414 0x04 0x00
- 0x40c 0x04 0x00
- 0x4f8 0x00 0x00
- 0x4fc 0x80 0x00
- 0x51c 0x40 0x00
- 0x444 0x71 0x00
- 0x43c 0x40 0x00
- 0x854 0x04 0x00
- 0x62c 0x52 0x00
- 0x9ac 0x00 0x00
- 0x8a0 0x01 0x00
- 0x9e0 0x00 0x00
- 0x9dc 0x01 0x00
- 0x9a8 0x00 0x00
- 0x8a4 0x01 0x00
- 0x8a8 0x73 0x00
- 0x9d8 0x99 0x00
- 0x9b0 0x03 0x00
- 0x804 0x03 0x00
- 0x800 0x00 0x00
- 0x808 0x03 0x00>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&pcie0_clkreq_default
- &pcie0_perst_default
- &pcie0_wake_default>;
-
- perst-gpio = <&tlmm 35 0>;
- wake-gpio = <&tlmm 37 0>;
-
- gdsc-vdd-supply = <&gdsc_pcie_0>;
- vreg-1.8-supply = <&pmcobalt_l2>;
- vreg-0.9-supply = <&pmcobalt_l1>;
- vreg-cx-supply = <&pmcobalt_s1_level>;
-
- qcom,vreg-1.8-voltage-level = <1200000 1200000 24000>;
- qcom,vreg-0.9-voltage-level = <880000 880000 24000>;
- qcom,vreg-cx-voltage-level = <RPM_SMD_REGULATOR_LEVEL_BINNING
- RPM_SMD_REGULATOR_LEVEL_SVS 0>;
-
- qcom,ep-latency = <10>;
-
- qcom,ep-wakeirq;
-
- linux,pci-domain = <0>;
-
- qcom,pcie-phy-ver = <0x20>;
- qcom,use-19p2mhz-aux-clk;
-
- iommus = <&anoc1_smmu>;
- qcom,smmu-exist;
- qcom,smmu-sid-base = <0x1480>;
-
- qcom,msm-bus,name = "pcie0";
- qcom,msm-bus,num-cases = <2>;
- qcom,msm-bus,num-paths = <1>;
- qcom,msm-bus,vectors-KBps =
- <45 512 0 0>,
- <45 512 500 800>;
-
- clocks = <&clock_gcc clk_gcc_pcie_0_pipe_clk>,
- <&clock_gcc clk_ln_bb_clk1>,
- <&clock_gcc clk_gcc_pcie_0_aux_clk>,
- <&clock_gcc clk_gcc_pcie_0_cfg_ahb_clk>,
- <&clock_gcc clk_gcc_pcie_0_mstr_axi_clk>,
- <&clock_gcc clk_gcc_pcie_0_slv_axi_clk>,
- <&clock_gcc clk_gcc_pcie_clkref_clk>;
-
- clock-names = "pcie_0_pipe_clk", "pcie_0_ref_clk_src",
- "pcie_0_aux_clk", "pcie_0_cfg_ahb_clk",
- "pcie_0_mstr_axi_clk", "pcie_0_slv_axi_clk",
- "pcie_0_ldo";
-
- max-clock-frequency-hz = <0>, <0>, <19200000>,
- <0>, <0>, <0>, <0>, <0>, <0>,
- <0>, <0>, <0>, <0>, <0>, <0>,
- <0>, <0>;
-
- resets = <&clock_gcc PCIE_PHY_BCR>,
- <&clock_gcc PCIE_0_PHY_BCR>,
- <&clock_gcc PCIE_0_PHY_BCR>;
-
- reset-names = "pcie_phy_reset",
- "pcie_0_phy_reset",
- "pcie_0_phy_pipe_reset";
- };
-
qcom,ipc_router {
compatible = "qcom,ipc_router";
qcom,node-id = <1>;
@@ -2158,6 +1984,32 @@
qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_2_out 0 0>;
};
+ qcom,memshare {
+ compatible = "qcom,memshare";
+
+ qcom,client_1 {
+ compatible = "qcom,memshare-peripheral";
+ qcom,peripheral-size = <0x200000>;
+ qcom,client-id = <0>;
+ qcom,allocate-boot-time;
+ label = "modem";
+ };
+
+ qcom,client_2 {
+ compatible = "qcom,memshare-peripheral";
+ qcom,peripheral-size = <0x300000>;
+ qcom,client-id = <2>;
+ label = "modem";
+ };
+
+ mem_client_3_size: qcom,client_3 {
+ compatible = "qcom,memshare-peripheral";
+ qcom,peripheral-size = <0x0>;
+ qcom,client-id = <1>;
+ label = "modem";
+ };
+ };
+
pil_modem: qcom,mss@4080000 {
compatible = "qcom,pil-q6v55-mss";
reg = <0x4080000 0x100>,
@@ -2584,6 +2436,229 @@
};
};
+ pcie0: qcom,pcie@01c00000 {
+ compatible = "qcom,pci-msm";
+ cell-index = <0>;
+
+ reg = <0x1c00000 0x2000>,
+ <0x1c06000 0x1000>,
+ <0x1b000000 0xf1d>,
+ <0x1b000f20 0xa8>,
+ <0x1b100000 0x100000>,
+ <0x1b200000 0x100000>,
+ <0x1b300000 0xd00000>;
+
+ reg-names = "parf", "phy", "dm_core", "elbi",
+ "conf", "io", "bars";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x01000000 0x0 0x1b200000 0x1b200000 0x0 0x100000>,
+ <0x02000000 0x0 0x1b300000 0x1b300000 0x0 0xd00000>;
+ interrupt-parent = <&pcie0>;
+ interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
+ 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
+ 36 37>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0xffffffff>;
+ interrupt-map = <0 0 0 0 &intc 0 0 405 0
+ 0 0 0 1 &intc 0 0 135 0
+ 0 0 0 2 &intc 0 0 136 0
+ 0 0 0 3 &intc 0 0 138 0
+ 0 0 0 4 &intc 0 0 139 0
+ 0 0 0 5 &intc 0 0 278 0
+ 0 0 0 6 &intc 0 0 576 0
+ 0 0 0 7 &intc 0 0 577 0
+ 0 0 0 8 &intc 0 0 578 0
+ 0 0 0 9 &intc 0 0 579 0
+ 0 0 0 10 &intc 0 0 580 0
+ 0 0 0 11 &intc 0 0 581 0
+ 0 0 0 12 &intc 0 0 582 0
+ 0 0 0 13 &intc 0 0 583 0
+ 0 0 0 14 &intc 0 0 584 0
+ 0 0 0 15 &intc 0 0 585 0
+ 0 0 0 16 &intc 0 0 586 0
+ 0 0 0 17 &intc 0 0 587 0
+ 0 0 0 18 &intc 0 0 588 0
+ 0 0 0 19 &intc 0 0 589 0
+ 0 0 0 20 &intc 0 0 590 0
+ 0 0 0 21 &intc 0 0 591 0
+ 0 0 0 22 &intc 0 0 592 0
+ 0 0 0 23 &intc 0 0 593 0
+ 0 0 0 24 &intc 0 0 594 0
+ 0 0 0 25 &intc 0 0 595 0
+ 0 0 0 26 &intc 0 0 596 0
+ 0 0 0 27 &intc 0 0 597 0
+ 0 0 0 28 &intc 0 0 598 0
+ 0 0 0 29 &intc 0 0 599 0
+ 0 0 0 30 &intc 0 0 600 0
+ 0 0 0 31 &intc 0 0 601 0
+ 0 0 0 32 &intc 0 0 602 0
+ 0 0 0 33 &intc 0 0 603 0
+ 0 0 0 34 &intc 0 0 604 0
+ 0 0 0 35 &intc 0 0 605 0
+ 0 0 0 36 &intc 0 0 606 0
+ 0 0 0 37 &intc 0 0 607 0>;
+
+ interrupt-names = "int_msi", "int_a", "int_b", "int_c",
+ "int_d", "int_global_int",
+ "msi_0", "msi_1", "msi_2", "msi_3",
+ "msi_4", "msi_5", "msi_6", "msi_7",
+ "msi_8", "msi_9", "msi_10", "msi_11",
+ "msi_12", "msi_13", "msi_14", "msi_15",
+ "msi_16", "msi_17", "msi_18", "msi_19",
+ "msi_20", "msi_21", "msi_22", "msi_23",
+ "msi_24", "msi_25", "msi_26", "msi_27",
+ "msi_28", "msi_29", "msi_30", "msi_31";
+
+ qcom,phy-sequence = <0x804 0x01 0x00
+ 0x034 0x14 0x00
+ 0x138 0x30 0x00
+ 0x048 0x0f 0x00
+ 0x15c 0x06 0x00
+ 0x090 0x01 0x00
+ 0x088 0x20 0x00
+ 0x0f0 0x00 0x00
+ 0x0f8 0x01 0x00
+ 0x0f4 0xc9 0x00
+ 0x11c 0xff 0x00
+ 0x120 0x3f 0x00
+ 0x164 0x01 0x00
+ 0x154 0x00 0x00
+ 0x148 0x0a 0x00
+ 0x05C 0x19 0x00
+ 0x038 0x90 0x00
+ 0x0b0 0x82 0x00
+ 0x0c0 0x03 0x00
+ 0x0bc 0x55 0x00
+ 0x0b8 0x55 0x00
+ 0x0a0 0x00 0x00
+ 0x09c 0x0d 0x00
+ 0x098 0x04 0x00
+ 0x13c 0x00 0x00
+ 0x060 0x08 0x00
+ 0x068 0x16 0x00
+ 0x070 0x34 0x00
+ 0x15c 0x06 0x00
+ 0x138 0x33 0x00
+ 0x03c 0x02 0x00
+ 0x040 0x0e 0x00
+ 0x080 0x04 0x00
+ 0x0dc 0x00 0x00
+ 0x0d8 0x3f 0x00
+ 0x00c 0x09 0x00
+ 0x010 0x01 0x00
+ 0x01c 0x40 0x00
+ 0x020 0x01 0x00
+ 0x014 0x02 0x00
+ 0x018 0x00 0x00
+ 0x024 0x7e 0x00
+ 0x028 0x15 0x00
+ 0x244 0x02 0x00
+ 0x2a4 0x12 0x00
+ 0x260 0x10 0x00
+ 0x28c 0x06 0x00
+ 0x504 0x03 0x00
+ 0x500 0x1c 0x00
+ 0x50c 0x14 0x00
+ 0x4d4 0x0a 0x00
+ 0x4d8 0x04 0x00
+ 0x4dc 0x1a 0x00
+ 0x434 0x4b 0x00
+ 0x414 0x04 0x00
+ 0x40c 0x04 0x00
+ 0x4f8 0x00 0x00
+ 0x4fc 0x80 0x00
+ 0x51c 0x40 0x00
+ 0x444 0x71 0x00
+ 0x43c 0x40 0x00
+ 0x854 0x04 0x00
+ 0x62c 0x52 0x00
+ 0x9ac 0x00 0x00
+ 0x8a0 0x01 0x00
+ 0x9e0 0x00 0x00
+ 0x9dc 0x01 0x00
+ 0x9a8 0x00 0x00
+ 0x8a4 0x01 0x00
+ 0x8a8 0x73 0x00
+ 0x9d8 0x99 0x00
+ 0x9b0 0x03 0x00
+ 0x804 0x03 0x00
+ 0x800 0x00 0x00
+ 0x808 0x03 0x00>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_clkreq_default
+ &pcie0_perst_default
+ &pcie0_wake_default>;
+
+ perst-gpio = <&tlmm 35 0>;
+ wake-gpio = <&tlmm 37 0>;
+
+ gdsc-vdd-supply = <&gdsc_pcie_0>;
+ vreg-1.8-supply = <&pmcobalt_l2>;
+ vreg-0.9-supply = <&pmcobalt_l1>;
+ vreg-cx-supply = <&pmcobalt_s1_level>;
+
+ qcom,vreg-1.8-voltage-level = <1200000 1200000 24000>;
+ qcom,vreg-0.9-voltage-level = <880000 880000 24000>;
+ qcom,vreg-cx-voltage-level = <RPM_SMD_REGULATOR_LEVEL_BINNING
+ RPM_SMD_REGULATOR_LEVEL_SVS 0>;
+
+ qcom,l1-supported;
+ qcom,l1ss-supported;
+ qcom,aux-clk-sync;
+
+ qcom,ep-latency = <10>;
+
+ qcom,ep-wakeirq;
+
+ linux,pci-domain = <0>;
+
+ qcom,msi-gicm-addr = <0x17a00040>;
+ qcom,msi-gicm-base = <0x260>;
+
+ qcom,pcie-phy-ver = <0x20>;
+ qcom,use-19p2mhz-aux-clk;
+
+ iommus = <&anoc1_smmu>;
+ qcom,smmu-exist;
+ qcom,smmu-sid-base = <0x1480>;
+
+ qcom,msm-bus,name = "pcie0";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <45 512 0 0>,
+ <45 512 500 800>;
+
+ clocks = <&clock_gcc clk_gcc_pcie_0_pipe_clk>,
+ <&clock_gcc clk_ln_bb_clk1>,
+ <&clock_gcc clk_gcc_pcie_0_aux_clk>,
+ <&clock_gcc clk_gcc_pcie_0_cfg_ahb_clk>,
+ <&clock_gcc clk_gcc_pcie_0_mstr_axi_clk>,
+ <&clock_gcc clk_gcc_pcie_0_slv_axi_clk>,
+ <&clock_gcc clk_gcc_pcie_clkref_clk>;
+
+ clock-names = "pcie_0_pipe_clk", "pcie_0_ref_clk_src",
+ "pcie_0_aux_clk", "pcie_0_cfg_ahb_clk",
+ "pcie_0_mstr_axi_clk", "pcie_0_slv_axi_clk",
+ "pcie_0_ldo";
+
+ max-clock-frequency-hz = <0>, <0>, <19200000>,
+ <0>, <0>, <0>, <0>, <0>, <0>,
+ <0>, <0>, <0>, <0>, <0>, <0>,
+ <0>, <0>;
+
+ resets = <&clock_gcc PCIE_PHY_BCR>,
+ <&clock_gcc PCIE_0_PHY_BCR>,
+ <&clock_gcc PCIE_0_PHY_BCR>;
+
+ reset-names = "pcie_phy_reset",
+ "pcie_0_phy_reset",
+ "pcie_0_phy_pipe_reset";
+ };
+
qcom,bcl {
compatible = "qcom,bcl";
qcom,bcl-enable;
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-blsp.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-blsp.dtsi
index 61764a095a29..c401d364409b 100644
--- a/arch/arm/boot/dts/qcom/msmfalcon-blsp.dtsi
+++ b/arch/arm/boot/dts/qcom/msmfalcon-blsp.dtsi
@@ -22,11 +22,203 @@
spi6 = &spi_6;
spi7 = &spi_7;
spi8 = &spi_8;
+ i2c1 = &i2c_1;
+ i2c2 = &i2c_2;
+ i2c3 = &i2c_3;
+ i2c4 = &i2c_4;
+ i2c5 = &i2c_5;
+ i2c6 = &i2c_6;
+ i2c7 = &i2c_7;
+ i2c8 = &i2c_8;
};
};
&soc {
+ i2c_1: i2c@c175000 { /* BLSP1 QUP1 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xc175000 0x600>;
+ reg-names = "qup_phys_addr";
+ interrupt-names = "qup_irq";
+ interrupts = <0 95 0>;
+ dmas = <&dma_blsp1 4 64 0x20000020 0x20>,
+ <&dma_blsp1 5 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <86>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
+ <&clock_gcc GCC_BLSP1_QUP1_I2C_APPS_CLK>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_1_active>;
+ pinctrl-1 = <&i2c_1_sleep>;
+ status = "disabled";
+ };
+
+ i2c_2: i2c@c176000 { /* BLSP1 QUP2 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xc176000 0x600>;
+ reg-names = "qup_phys_addr";
+ interrupt-names = "qup_irq";
+ interrupts = <0 96 0>;
+ dmas = <&dma_blsp1 6 64 0x20000020 0x20>,
+ <&dma_blsp1 7 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <86>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
+ <&clock_gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_2_active>;
+ pinctrl-1 = <&i2c_2_sleep>;
+ status = "disabled";
+ };
+
+ i2c_3: i2c@c177000 { /* BLSP1 QUP3 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xc177000 0x600>;
+ reg-names = "qup_phys_addr";
+ interrupt-names = "qup_irq";
+ interrupts = <0 97 0>;
+ dmas = <&dma_blsp1 8 64 0x20000020 0x20>,
+ <&dma_blsp1 9 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <86>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
+ <&clock_gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_3_active>;
+ pinctrl-1 = <&i2c_3_sleep>;
+ status = "disabled";
+ };
+
+ i2c_4: i2c@c178000 { /* BLSP1 QUP4 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xc178000 0x600>;
+ reg-names = "qup_phys_addr";
+ interrupt-names = "qup_irq";
+ interrupts = <0 98 0>;
+ dmas = <&dma_blsp1 10 64 0x20000020 0x20>,
+ <&dma_blsp1 11 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <86>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
+ <&clock_gcc GCC_BLSP1_QUP4_I2C_APPS_CLK>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_4_active>;
+ pinctrl-1 = <&i2c_4_sleep>;
+ status = "disabled";
+ };
+
+ i2c_5: i2c@c1b5000 { /* BLSP2 QUP1 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xc1b5000 0x600>;
+ reg-names = "qup_phys_addr";
+ interrupt-names = "qup_irq";
+ interrupts = <0 101 0>;
+ dmas = <&dma_blsp2 4 64 0x20000020 0x20>,
+ <&dma_blsp2 5 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <84>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>,
+ <&clock_gcc GCC_BLSP2_QUP1_I2C_APPS_CLK>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_5_active>;
+ pinctrl-1 = <&i2c_5_sleep>;
+ status = "disabled";
+ };
+
+ i2c_6: i2c@c1b6000 { /* BLSP2 QUP2 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xc1b6000 0x600>;
+ reg-names = "qup_phys_addr";
+ interrupt-names = "qup_irq";
+ interrupts = <0 102 0>;
+ dmas = <&dma_blsp2 6 64 0x20000020 0x20>,
+ <&dma_blsp2 7 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <84>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>,
+ <&clock_gcc GCC_BLSP2_QUP2_I2C_APPS_CLK>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_6_active>;
+ pinctrl-1 = <&i2c_6_sleep>;
+ status = "disabled";
+ };
+
+ i2c_7: i2c@c1b7000 { /* BLSP2 QUP3 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xc1b7000 0x600>;
+ reg-names = "qup_phys_addr";
+ interrupt-names = "qup_irq";
+ interrupts = <0 103 0>;
+ dmas = <&dma_blsp2 8 64 0x20000020 0x20>,
+ <&dma_blsp2 9 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <84>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>,
+ <&clock_gcc GCC_BLSP2_QUP3_I2C_APPS_CLK>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_7_active>;
+ pinctrl-1 = <&i2c_7_sleep>;
+ status = "disabled";
+ };
+
+ i2c_8: i2c@c1b8000 { /* BLSP2 QUP4 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xc1b8000 0x600>;
+ reg-names = "qup_phys_addr";
+ interrupt-names = "qup_irq";
+ interrupts = <0 104 0>;
+ dmas = <&dma_blsp2 10 64 0x20000020 0x20>,
+ <&dma_blsp2 11 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <84>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>,
+ <&clock_gcc GCC_BLSP2_QUP4_I2C_APPS_CLK>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_8_active>;
+ pinctrl-1 = <&i2c_8_sleep>;
+ status = "disabled";
+ };
+
spi_1: spi@c175000 { /* BLSP1 QUP1 */
compatible = "qcom,spi-qup-v2";
#address-cells = <1>;
@@ -226,4 +418,152 @@
<&clock_gcc GCC_BLSP2_QUP4_SPI_APPS_CLK>;
status = "disabled";
};
+
+ blsp1_uart1_hs: uart@c16f000 { /* BLSP1 UART1 */
+ compatible = "qcom,msm-hsuart-v14";
+ reg = <0xc16f000 0x200>,
+ <0xc144000 0x1f000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp1_uart1_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 0 107 0
+ 1 &intc 0 0 238 0
+ 2 &tlmm 1 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xfd>;
+
+ qcom,bam-tx-ep-pipe-index = <0>;
+ qcom,bam-rx-ep-pipe-index = <1>;
+ qcom,master-id = <86>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc GCC_BLSP1_UART1_APPS_CLK>,
+ <&clock_gcc GCC_BLSP1_AHB_CLK>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp1_uart1_sleep>;
+ pinctrl-1 = <&blsp1_uart1_active>;
+
+ qcom,msm-bus,name = "buart1";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <86 512 0 0>,
+ <86 512 500 800>;
+ status = "disabled";
+ };
+
+ blsp1_uart2_hs: uart@c170000 { /* BLSP1 UART2 */
+ compatible = "qcom,msm-hsuart-v14";
+ reg = <0xc170000 0x200>,
+ <0xc144000 0x1f000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp1_uart2_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 0 108 0
+ 1 &intc 0 0 238 0
+ 2 &tlmm 5 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xfd>;
+
+ qcom,bam-tx-ep-pipe-index = <2>;
+ qcom,bam-rx-ep-pipe-index = <3>;
+ qcom,master-id = <86>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc GCC_BLSP1_UART2_APPS_CLK>,
+ <&clock_gcc GCC_BLSP1_AHB_CLK>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp1_uart2_sleep>;
+ pinctrl-1 = <&blsp1_uart2_active>;
+
+ qcom,msm-bus,name = "buart2";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <86 512 0 0>,
+ <86 512 500 800>;
+ status = "disabled";
+ };
+
+ blsp2_uart1_hs: uart@c1af000 { /* BLSP2 UART1 */
+ compatible = "qcom,msm-hsuart-v14";
+ reg = <0xc1af000 0x200>,
+ <0xc184000 0x1f000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp2_uart1_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 0 113 0
+ 1 &intc 0 0 239 0
+ 2 &tlmm 17 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xfd>;
+
+ qcom,bam-tx-ep-pipe-index = <0>;
+ qcom,bam-rx-ep-pipe-index = <1>;
+ qcom,master-id = <84>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc GCC_BLSP2_UART1_APPS_CLK>,
+ <&clock_gcc GCC_BLSP2_AHB_CLK>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp2_uart1_sleep>;
+ pinctrl-1 = <&blsp2_uart1_active>;
+
+ qcom,msm-bus,name = "buart3";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <84 512 0 0>,
+ <84 512 500 800>;
+ status = "disabled";
+ };
+
+ blsp2_uart2_hs: uart@c1b0000 { /* BLSP2 UART2 */
+ compatible = "qcom,msm-hsuart-v14";
+ reg = <0xc1b0000 0x200>,
+ <0xc184000 0x1f000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp2_uart2_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 0 114 0
+ 1 &intc 0 0 239 0
+ 2 &tlmm 25 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xfd>;
+
+ qcom,bam-tx-ep-pipe-index = <2>;
+ qcom,bam-rx-ep-pipe-index = <3>;
+ qcom,master-id = <84>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc GCC_BLSP2_UART2_APPS_CLK>,
+ <&clock_gcc GCC_BLSP2_AHB_CLK>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp2_uart2_sleep>;
+ pinctrl-1 = <&blsp2_uart2_active>;
+
+ qcom,msm-bus,name = "buart4";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <84 512 0 0>,
+ <84 512 500 800>;
+ status = "disabled";
+ };
};
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi
index f13e34f8296b..90aa771332a3 100644
--- a/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi
@@ -22,12 +22,12 @@
uart_console_active: uart_console_active {
mux {
- pins = "gpio0", "gpio1";
- function = "blsp_uart1";
+ pins = "gpio4", "gpio5";
+ function = "blsp_uart2";
};
config {
- pins = "gpio0", "gpio1";
+ pins = "gpio4", "gpio5";
drive-strength = <2>;
bias-disable;
};
@@ -113,6 +113,231 @@
};
};
+ /* I2C CONFIGURATION */
+ i2c_1 {
+ i2c_1_active: i2c_1_active {
+ mux {
+ pins = "gpio2", "gpio3";
+ function = "blsp_i2c1";
+ };
+
+ config {
+ pins = "gpio2", "gpio3";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_1_sleep: i2c_1_sleep {
+ mux {
+ pins = "gpio2", "gpio3";
+ function = "blsp_i2c1";
+ };
+
+ config {
+ pins = "gpio2", "gpio3";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_2 {
+ i2c_2_active: i2c_2_active {
+ mux {
+ pins = "gpio6", "gpio7";
+ function = "blsp_i2c2";
+ };
+
+ config {
+ pins = "gpio6", "gpio7";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_2_sleep: i2c_2_sleep {
+ mux {
+ pins = "gpio6", "gpio7";
+ function = "blsp_i2c2";
+ };
+
+ config {
+ pins = "gpio6", "gpio7";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_3 {
+ i2c_3_active: i2c_3_active {
+ mux {
+ pins = "gpio10", "gpio11";
+ function = "blsp_i2c3";
+ };
+
+ config {
+ pins = "gpio10", "gpio11";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_3_sleep: i2c_3_sleep {
+ mux {
+ pins = "gpio10", "gpio11";
+ function = "blsp_i2c3";
+ };
+
+ config {
+ pins = "gpio10", "gpio11";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_4 {
+ i2c_4_active: i2c_4_active {
+ mux {
+ pins = "gpio14", "gpio15";
+ function = "blsp_i2c4";
+ };
+
+ config {
+ pins = "gpio14", "gpio15";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_4_sleep: i2c_4_sleep {
+ mux {
+ pins = "gpio14", "gpio15";
+ function = "blsp_i2c4";
+ };
+
+ config {
+ pins = "gpio14", "gpio15";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_5 {
+ i2c_5_active: i2c_5_active {
+ mux {
+ pins = "gpio18", "gpio19";
+ function = "blsp_i2c5";
+ };
+
+ config {
+ pins = "gpio18", "gpio19";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_5_sleep: i2c_5_sleep {
+ mux {
+ pins = "gpio18", "gpio19";
+ function = "blsp_i2c5";
+ };
+
+ config {
+ pins = "gpio18", "gpio19";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_6 {
+ i2c_6_active: i2c_6_active {
+ mux {
+ pins = "gpio22", "gpio23";
+ function = "blsp_i2c6";
+ };
+
+ config {
+ pins = "gpio22", "gpio23";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_6_sleep: i2c_6_sleep {
+ mux {
+ pins = "gpio22", "gpio23";
+ function = "blsp_i2c6";
+ };
+
+ config {
+ pins = "gpio22", "gpio23";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_7 {
+ i2c_7_active: i2c_7_active {
+ mux {
+ pins = "gpio26", "gpio27";
+ function = "blsp_i2c7";
+ };
+
+ config {
+ pins = "gpio26", "gpio27";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_7_sleep: i2c_7_sleep {
+ mux {
+ pins = "gpio26", "gpio27";
+ function = "blsp_i2c7";
+ };
+
+ config {
+ pins = "gpio26", "gpio27";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_8 {
+ i2c_8_active: i2c_8_active {
+ mux {
+ pins = "gpio30", "gpio31";
+ function = "blsp_i2c8_a";
+ };
+
+ config {
+ pins = "gpio30", "gpio31";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_8_sleep: i2c_8_sleep {
+ mux {
+ pins = "gpio30", "gpio31";
+ function = "blsp_i2c8_a";
+ };
+
+ config {
+ pins = "gpio30", "gpio31";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
/* SPI CONFIGURATION */
spi_1 {
spi_1_active: spi_1_active {
@@ -369,5 +594,110 @@
};
};
};
+
+ /* HS UART CONFIGURATION */
+ blsp1_uart1_active: blsp1_uart1_active {
+ mux {
+ pins = "gpio0", "gpio1", "gpio2", "gpio3";
+ function = "blsp_uart1";
+ };
+
+ config {
+ pins = "gpio0", "gpio1", "gpio2", "gpio3";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart1_sleep: blsp1_uart1_sleep {
+ mux {
+ pins = "gpio0", "gpio1", "gpio2", "gpio3";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio0", "gpio1", "gpio2", "gpio3";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart2_active: blsp1_uart2_active {
+ mux {
+ pins = "gpio4", "gpio5", "gpio6", "gpio7";
+ function = "blsp_uart2 ";
+ };
+
+ config {
+ pins = "gpio4", "gpio5", "gpio6", "gpio7";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart2_sleep: blsp1_uart2_sleep {
+ mux {
+ pins = "gpio4", "gpio5", "gpio6", "gpio7";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio4", "gpio5", "gpio6", "gpio7";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp2_uart1_active: blsp2_uart1_active {
+ mux {
+ pins = "gpio16", "gpio17", "gpio18", "gpio19";
+ function = "blsp_uart5";
+ };
+
+ config {
+ pins = "gpio16", "gpio17", "gpio18", "gpio19";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp2_uart1_sleep: blsp2_uart1_sleep {
+ mux {
+ pins = "gpio16", "gpio17", "gpio18", "gpio19";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio16", "gpio17", "gpio18", "gpio19";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp2_uart2_active: blsp2_uart2_active {
+ mux {
+ pins = "gpio24", "gpio25", "gpio26", "gpio27";
+ function = "blsp_uart6_a";
+ };
+
+ config {
+ pins = "gpio24", "gpio25", "gpio26", "gpio27";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp2_uart2_sleep: blsp2_uart2_sleep {
+ mux {
+ pins = "gpio24", "gpio25", "gpio26", "gpio27";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio24", "gpio25", "gpio26", "gpio27";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi
index 124ab341ba6b..cfe968a7310a 100644
--- a/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi
+++ b/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi
@@ -10,351 +10,438 @@
* GNU General Public License for more details.
*/
-/* Stub regulators */
-
-/ {
- /* PMFALCON S1 - VDD_APC0 supply */
- pmfalcon_s1a: regulator-pmfalcon-s1a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s1a";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <565000>;
- regulator-max-microvolt = <1170000>;
- };
-
- /* PMFALCON S2 + S3 = VDD_APC1 supply */
- pmfalcon_s2a: regulator-pmfalcon-s2a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s2a";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <565000>;
- regulator-max-microvolt = <1170000>;
- };
-
- pmfalcon_s4a: regulator-pmfalcon-s4a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s4a";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <1805000>;
- regulator-max-microvolt = <2040000>;
- };
-
- pmfalcon_s5a: regulator-pmfalcon-s5a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s5a";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <1350000>;
- regulator-max-microvolt = <1350000>;
- };
-
- pmfalcon_s6a: regulator-pmfalcon-s6a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s6a";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <504000>;
- regulator-max-microvolt = <992000>;
- };
-
- pmfalcon_s1b: regulator-pmfalcon-s1b {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s1b";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <1125000>;
- regulator-max-microvolt = <1125000>;
- };
-
- pmfalcon_s2b: regulator-pmfalcon-s2b {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s2b";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <1050000>;
- regulator-max-microvolt = <1050000>;
- };
-
- /* PMFALCON S3 + S4 - VDD_CX supply */
- pmfalcon_s3b_level: regulator-pmfalcon-s3b-level {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s3b_level";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
- regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
- };
-
- pmfalcon_s3b_floor_level: regulator-pmfalcon-s3b-floor-level {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s3b_floor_level";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
- regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
- };
-
- pmfalcon_s3b_level_ao: regulator-pmfalcon-s3b-level-ao {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s3b_level_ao";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
- regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
- };
-
- /* PMFALCON S5 - VDD_MX supply */
- pmfalcon_s5b_level: regulator-pmfalcon-s5b-level {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s5b_level";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
- regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
- };
-
- pmfalcon_s5b_floor_level: regulator-pmfalcon-s5b-floor-level {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s5b_floor_level";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
- regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
- };
-
- pmfalcon_s5b_level_ao: regulator-pmfalcon-s5b-level-ao {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s5b_level_ao";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
- regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
- };
-
- pmfalcon_l1a: regulator-pmfalcon-l1a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l1a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1150000>;
- regulator-max-microvolt = <1250000>;
- };
-
- pmfalcon_l2a: regulator-pmfalcon-l2a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l2a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <950000>;
- regulator-max-microvolt = <1010000>;
- };
-
- pmfalcon_l3a: regulator-pmfalcon-l3a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l3a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <950000>;
- regulator-max-microvolt = <1010000>;
+&rpm_bus {
+ rpm-regulator-smpa4 {
+ status = "okay";
+ pmfalcon_s4: regulator-s4 {
+ regulator-min-microvolt = <1805000>;
+ regulator-max-microvolt = <2040000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-smpa5 {
+ status = "okay";
+ pmfalcon_s5: regulator-s5 {
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-smpa6 {
+ status = "okay";
+ pmfalcon_s6: regulator-s6 {
+ regulator-min-microvolt = <504000>;
+ regulator-max-microvolt = <992000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-smpb1 {
+ status = "okay";
+ pm2falcon_s1: regulator-s1 {
+ regulator-min-microvolt = <1125000>;
+ regulator-max-microvolt = <1125000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-smpb2 {
+ status = "okay";
+ pm2falcon_s2: regulator-s2 {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ status = "okay";
+ };
+ };
+
+ /* PM2FALCON S3 + S4 - VDD_CX supply */
+ rpm-regulator-smpb3 {
+ status = "okay";
+ pm2falcon_s3_level: regulator-s3-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_s3_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-level;
+ };
+
+ pm2falcon_s3_floor_level: regulator-s3-floor-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_s3_floor_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-floor-level;
+ qcom,always-send-voltage;
+ };
+
+ pm2falcon_s3_level_ao: regulator-s3-level-ao {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_s3_level_ao";
+ qcom,set = <1>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-level;
+ };
+ };
+
+ /* PM2FALCON S5 - VDD_MX supply */
+ rpm-regulator-smpb5 {
+ status = "okay";
+ pm2falcon_s5_level: regulator-s5-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_s5_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-level;
+ };
+
+ pm2falcon_s5_floor_level: regulator-s5-floor-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_s5_floor_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-floor-level;
+ qcom,always-send-voltage;
+ };
+
+ pm2falcon_s5_level_ao: regulator-s5-level-ao {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_s5_level_ao";
+ qcom,set = <1>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-level;
+ };
+ };
+
+ rpm-regulator-ldoa1 {
+ status = "okay";
+ pmfalcon_l1: regulator-l1 {
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1250000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa2 {
+ status = "okay";
+ pmfalcon_l2: regulator-l2 {
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1010000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa3 {
+ status = "okay";
+ pmfalcon_l3: regulator-l3 {
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1010000>;
+ status = "okay";
+ };
};
/* TODO: remove if ADRASTEA CX/MX not voted from APPS */
- pmfalcon_l5a: regulator-pmfalcon-l5a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l5a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <525000>;
- regulator-max-microvolt = <950000>;
- };
-
- pmfalcon_l6a: regulator-pmfalcon-l6a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l6a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1370000>;
- };
-
- pmfalcon_l7a: regulator-pmfalcon-l7a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l7a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- };
-
- pmfalcon_l8a: regulator-pmfalcon-l8a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l8a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1750000>;
- regulator-max-microvolt = <1900000>;
- };
-
- pmfalcon_l9a: regulator-pmfalcon-l9a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l9a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1750000>;
- regulator-max-microvolt = <1900000>;
- };
-
- pmfalcon_l10a: regulator-pmfalcon-l10a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l10a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1780000>;
- regulator-max-microvolt = <1950000>;
- };
-
- pmfalcon_l11a: regulator-pmfalcon-l11a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l11a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1780000>;
- regulator-max-microvolt = <1950000>;
- };
-
- pmfalcon_l12a: regulator-pmfalcon-l12a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l12a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1780000>;
- regulator-max-microvolt = <1950000>;
- };
-
- pmfalcon_l13a: regulator-pmfalcon-l13a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l13a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1750000>;
- regulator-max-microvolt = <1950000>;
- };
-
- pmfalcon_l14a: regulator-pmfalcon-l14a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l14a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1710000>;
- regulator-max-microvolt = <1900000>;
- };
-
- pmfalcon_l15a: regulator-pmfalcon-l15a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l15a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1650000>;
- regulator-max-microvolt = <2950000>;
- };
-
- pmfalcon_l17a: regulator-pmfalcon-l17a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l17a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1650000>;
- regulator-max-microvolt = <2950000>;
- };
-
- pmfalcon_l19a: regulator-pmfalcon-l19a {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l19a";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <3200000>;
- regulator-max-microvolt = <3400000>;
- };
-
- pmfalcon_l1b: regulator-pmfalcon-l1b {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l1b";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <800000>;
- regulator-max-microvolt = <925000>;
- };
-
- pmfalcon_l2b: regulator-pmfalcon-l2b {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l2b";
- qcom,hpm-min-load = <5000>;
- regulator-min-microvolt = <350000>;
- regulator-max-microvolt = <3100000>;
- };
-
- pmfalcon_l3b: regulator-pmfalcon-l3b {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l3b";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1710000>;
- regulator-max-microvolt = <3600000>;
- };
-
- pmfalcon_l4b: regulator-pmfalcon-l4b {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l4b";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1700000>;
- regulator-max-microvolt = <2950000>;
- };
-
- pmfalcon_l5b: regulator-pmfalcon-l5b {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l5b";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1721000>;
- regulator-max-microvolt = <3600000>;
- };
-
- pmfalcon_l6b: regulator-pmfalcon-l6b {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l6b";
- qcom,hpm-min-load = <5000>;
- regulator-min-microvolt = <1700000>;
- regulator-max-microvolt = <3300000>;
- };
-
- pmfalcon_l7b: regulator-pmfalcon-l7b {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l7b";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <2700000>;
- regulator-max-microvolt = <3125000>;
- };
-
- pmfalcon_l8b: regulator-pmfalcon-l8b {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l8b";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <3200000>;
- regulator-max-microvolt = <3400000>;
- };
-
- /* PMFALCON L9 = VDD_SSC_CX supply */
- pmfalcon_l9b_level: regulator-pmfalcon-l9b-level {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l9b_level";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
- regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
- };
-
- pmfalcon_l9b_floor_level: regulator-pmfalcon-l9b-floor-level {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l9b_floor_level";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
- regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
- };
-
- /* PMFALCON L10 = VDD_SSC_MX supply */
- pmfalcon_l10b_level: regulator-pmfalcon-l10b-level {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l10b_level";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
- regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
- };
-
- pmfalcon_l10b_floor_level: regulator-pmfalcon-l10b-floor-level {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l10b_floor_level";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
- regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
- };
-
- pmfalcon_bob: regulator-pmfalcon-bob {
- compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_bob";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
+ rpm-regulator-ldoa5 {
+ status = "okay";
+ pmfalcon_l5: regulator-l5 {
+ regulator-min-microvolt = <525000>;
+ regulator-max-microvolt = <950000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa6 {
+ status = "okay";
+ pmfalcon_l6: regulator-l6 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1370000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa7 {
+ status = "okay";
+ pmfalcon_l7: regulator-l7 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa8 {
+ status = "okay";
+ pmfalcon_l8: regulator-l8 {
+ regulator-min-microvolt = <1750000>;
+ regulator-max-microvolt = <1900000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa9 {
+ status = "okay";
+ pmfalcon_l9: regulator-l9 {
+ regulator-min-microvolt = <1750000>;
+ regulator-max-microvolt = <1900000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa10 {
+ status = "okay";
+ pmfalcon_l10: regulator-l10 {
+ regulator-min-microvolt = <1780000>;
+ regulator-max-microvolt = <1950000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa11 {
+ status = "okay";
+ pmfalcon_l11: regulator-l11 {
+ regulator-min-microvolt = <1780000>;
+ regulator-max-microvolt = <1950000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa12 {
+ status = "okay";
+ pmfalcon_l12: regulator-l12 {
+ regulator-min-microvolt = <1780000>;
+ regulator-max-microvolt = <1950000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa13 {
+ status = "okay";
+ pmfalcon_l13: regulator-l13 {
+ regulator-min-microvolt = <1780000>;
+ regulator-max-microvolt = <1950000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa14 {
+ status = "okay";
+ pmfalcon_l14: regulator-l14 {
+ regulator-min-microvolt = <1710000>;
+ regulator-max-microvolt = <1900000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa15 {
+ status = "okay";
+ pmfalcon_l15: regulator-l15 {
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <2950000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa17 {
+ status = "okay";
+ pmfalcon_l17: regulator-l17 {
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <2950000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa19 {
+ status = "okay";
+ pmfalcon_l19: regulator-l19 {
+ regulator-min-microvolt = <3200000>;
+ regulator-max-microvolt = <3400000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldob1 {
+ status = "okay";
+ pm2falcon_l1: regulator-l1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <925000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldob2 {
+ status = "okay";
+ pm2falcon_l2: regulator-l2 {
+ regulator-min-microvolt = <350000>;
+ regulator-max-microvolt = <3100000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldob3 {
+ status = "okay";
+ pm2falcon_l3: regulator-l3 {
+ regulator-min-microvolt = <1710000>;
+ regulator-max-microvolt = <3600000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldob4 {
+ status = "okay";
+ pm2falcon_l4: regulator-l4 {
+ regulator-min-microvolt = <1700000>;
+ regulator-max-microvolt = <2950000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldob5 {
+ status = "okay";
+ pm2falcon_l5: regulator-l5 {
+ regulator-min-microvolt = <1721000>;
+ regulator-max-microvolt = <3600000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldob6 {
+ status = "okay";
+ pm2falcon_l6: regulator-l6 {
+ regulator-min-microvolt = <1700000>;
+ regulator-max-microvolt = <3300000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldob7 {
+ status = "okay";
+ pm2falcon_l7: regulator-l7 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3125000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldob8 {
+ status = "okay";
+ pm2falcon_l8: regulator-l8 {
+ regulator-min-microvolt = <3200000>;
+ regulator-max-microvolt = <3400000>;
+ status = "okay";
+ };
+ };
+
+ /* PM2FALCON L9 = VDD_SSC_CX supply */
+ rpm-regulator-ldob9 {
+ status = "okay";
+ pm2falcon_l9_level: regulator-l9-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_l9_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-level;
+ };
+
+ pm2falcon_l9_floor_level: regulator-l9-floor-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_l9_floor_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-floor-level;
+ qcom,always-send-voltage;
+ };
+ };
+
+ /* PM2FALCON L10 = VDD_SSC_MX supply */
+ rpm-regulator-ldob10 {
+ status = "okay";
+ pm2falcon_l10_level: regulator-l10-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_l10_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-level;
+ };
+
+ pm2falcon_l10_floor_level: regulator-l10-floor-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_l10_floor_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-floor-level;
+ qcom,always-send-voltage;
+ };
+ };
+
+ rpm-regulator-bobb {
+ status = "okay";
+ pm2falcon_bob: regulator-bob {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3600000>;
+ status = "okay";
+ };
+
+ pm2falcon_bob_pin1: regulator-bob-pin1 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_bob_pin1";
+ qcom,set = <3>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3600000>;
+ qcom,use-pin-ctrl-voltage1;
+ };
+
+ pm2falcon_bob_pin2: regulator-bob-pin2 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_bob_pin2";
+ qcom,set = <3>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3600000>;
+ qcom,use-pin-ctrl-voltage2;
+ };
+
+ pm2falcon_bob_pin3: regulator-bob-pin3 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm2falcon_bob_pin3";
+ qcom,set = <3>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3600000>;
+ qcom,use-pin-ctrl-voltage3;
+ };
};
+};
+/* Stub regulators */
+/ {
/* GFX Supply */
gfx_vreg_corner: regulator-gfx-corner {
compatible = "qcom,stub-regulator";
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts b/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts
index f0ba8b115120..c94ba0df3e6e 100644
--- a/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts
+++ b/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts
@@ -20,6 +20,10 @@
model = "Qualcomm Technologies, Inc. MSM FALCON RUMI";
compatible = "qcom,msmfalcon-rumi", "qcom,msmfalcon", "qcom,rumi";
qcom,board-id = <15 0>;
+
+ chosen {
+ bootargs = "lpm_levels.sleep_disabled=1";
+ };
};
&uartblsp1dm1 {
@@ -30,12 +34,12 @@
&sdhc_1 {
/* device core power supply */
- vdd-supply = <&pmfalcon_l4b>;
+ vdd-supply = <&pm2falcon_l4>;
qcom,vdd-voltage-level = <2950000 2950000>;
qcom,vdd-current-level = <200 570000>;
/* device communication power supply */
- vdd-io-supply = <&pmfalcon_l8a>;
+ vdd-io-supply = <&pmfalcon_l8>;
qcom,vdd-io-always-on;
qcom,vdd-io-lpm-sup;
qcom,vdd-io-voltage-level = <1800000 1800000>;
@@ -53,3 +57,8 @@
status = "ok";
};
+
+&clock_gcc {
+ compatible = "qcom,dummycc";
+ clock-output-names = "gcc_clocks";
+};
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-sim.dts b/arch/arm/boot/dts/qcom/msmfalcon-sim.dts
index 085419b7e108..00d97c8fdd32 100644
--- a/arch/arm/boot/dts/qcom/msmfalcon-sim.dts
+++ b/arch/arm/boot/dts/qcom/msmfalcon-sim.dts
@@ -20,6 +20,10 @@
model = "Qualcomm Technologies, Inc. MSM FALCON SIM";
compatible = "qcom,msmfalcon-sim", "qcom,msmfalcon", "qcom,sim";
qcom,board-id = <16 0>;
+
+ chosen {
+ bootargs = "lpm_levels.sleep_disabled=1";
+ };
};
&uartblsp1dm1 {
@@ -30,12 +34,12 @@
&sdhc_1 {
/* device core power supply */
- vdd-supply = <&pmfalcon_l4b>;
+ vdd-supply = <&pm2falcon_l4>;
qcom,vdd-voltage-level = <2950000 2950000>;
qcom,vdd-current-level = <200 570000>;
/* device communication power supply */
- vdd-io-supply = <&pmfalcon_l8a>;
+ vdd-io-supply = <&pmfalcon_l8>;
qcom,vdd-io-always-on;
qcom,vdd-io-lpm-sup;
qcom,vdd-io-voltage-level = <1800000 1800000>;
diff --git a/arch/arm/boot/dts/qcom/msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmfalcon.dtsi
index f2adc32fb732..9f6621b8847b 100644
--- a/arch/arm/boot/dts/qcom/msmfalcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msmfalcon.dtsi
@@ -249,6 +249,22 @@
clock-frequency = <19200000>;
};
+ dma_blsp1: qcom,sps-dma@0xc144000{ /* BLSP1 */
+ #dma-cells = <4>;
+ compatible = "qcom,sps-dma";
+ reg = <0xc144000 0x1F000>;
+ interrupts = <0 238 0>;
+ qcom,summing-threshold = <0x10>;
+ };
+
+ dma_blsp2: qcom,sps-dma@0xc184000{ /* BLSP2 */
+ #dma-cells = <4>;
+ compatible = "qcom,sps-dma";
+ reg = <0xc184000 0x1F000>;
+ interrupts = <0 239 0>;
+ qcom,summing-threshold = <0x10>;
+ };
+
spmi_bus: qcom,spmi@800f000 {
compatible = "qcom,spmi-pmic-arb";
reg = <0x800f000 0x1000>,
@@ -287,6 +303,32 @@
qcom,pipe-attr-ee;
};
+ qcom,memshare {
+ compatible = "qcom,memshare";
+
+ qcom,client_1 {
+ compatible = "qcom,memshare-peripheral";
+ qcom,peripheral-size = <0x200000>;
+ qcom,client-id = <0>;
+ qcom,allocate-boot-time;
+ label = "modem";
+ };
+
+ qcom,client_2 {
+ compatible = "qcom,memshare-peripheral";
+ qcom,peripheral-size = <0x300000>;
+ qcom,client-id = <2>;
+ label = "modem";
+ };
+
+ mem_client_3_size: qcom,client_3 {
+ compatible = "qcom,memshare-peripheral";
+ qcom,peripheral-size = <0x0>;
+ qcom,client-id = <1>;
+ label = "modem";
+ };
+ };
+
tsens: tsens@10ad000 {
compatible = "qcom,msmfalcon-tsens";
reg = <0x10ad000 0x2000>,
@@ -319,6 +361,31 @@
clock-names = "core", "iface";
};
+ slim_aud: slim@151c0000 {
+ cell-index = <1>;
+ compatible = "qcom,slim-ngd";
+ reg = <0x151c0000 0x2c000>,
+ <0x15180000 0x2e000>;
+ reg-names = "slimbus_physical", "slimbus_bam_physical";
+ interrupts = <0 163 0>, <0 164 0>;
+ interrupt-names = "slimbus_irq", "slimbus_bam_irq";
+ qcom,apps-ch-pipes = <0x7e0000>;
+ qcom,ea-pc = <0x260>;
+ status = "disabled";
+ };
+
+ slim_qca: slim@15240000 {
+ cell-index = <3>;
+ compatible = "qcom,slim-ngd";
+ reg = <0x15240000 0x2c000>,
+ <0x15200000 0x24000>;
+ reg-names = "slimbus_physical", "slimbus_bam_physical";
+ interrupts = <0 291 0>, <0 292 0>;
+ interrupt-names = "slimbus_irq", "slimbus_bam_irq";
+ qcom,apps-ch-pipes = <0x1800>;
+ status = "disabled";
+ };
+
timer@17920000 {
#address-cells = <1>;
#size-cells = <1>;
@@ -384,8 +451,10 @@
};
clock_gcc: clock-controller@100000 {
- compatible = "qcom,dummycc";
- clock-output-names = "gcc_clocks";
+ compatible = "qcom,gcc-msmfalcon";
+ reg = <0x100000 0x94000>;
+ vdd_dig-supply = <&pm2falcon_s3_level>;
+ vdd_dig_ao-supply = <&pm2falcon_s3_level_ao>;
#clock-cells = <1>;
#reset-cells = <1>;
};
@@ -696,7 +765,7 @@
reg = <0x15700000 0x00100>;
interrupts = <0 162 1>;
- vdd_cx-supply = <&pmfalcon_s3b_level>;
+ vdd_cx-supply = <&pm2falcon_s3_level>;
qcom,proxy-reg-names = "vdd_cx";
qcom,vdd_cx-uV-uA = <RPM_SMD_REGULATOR_LEVEL_TURBO 100000>;
@@ -728,7 +797,7 @@
reg = <0x1a300000 0x00100>;
interrupts = <0 518 1>;
- vdd_cx-supply = <&pmfalcon_s3b_level>;
+ vdd_cx-supply = <&pm2falcon_s3_level>;
qcom,proxy-reg-names = "vdd_cx";
qcom,vdd_cx-uV-uA = <RPM_SMD_REGULATOR_LEVEL_TURBO 100000>;
@@ -783,9 +852,9 @@
"mnoc_axi_clk";
interrupts = <0 448 1>;
- vdd_cx-supply = <&pmfalcon_s3b_level>;
+ vdd_cx-supply = <&pm2falcon_s3_level>;
vdd_cx-voltage = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
- vdd_mx-supply = <&pmfalcon_s5b_level>;
+ vdd_mx-supply = <&pm2falcon_s5_level>;
vdd_mx-uV = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
qcom,firmware-name = "modem";
qcom,pil-self-auth;
@@ -807,10 +876,25 @@
qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
status = "ok";
};
+
+ qcom,msm-imem@146bf000 {
+ compatible = "qcom,msm-imem";
+ reg = <0x146bf000 0x1000>;
+ ranges = <0x0 0x146bf000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pil@94c {
+ compatible = "qcom,msm-imem-pil";
+ reg = <0x94c 200>;
+ };
+ };
};
#include "msmfalcon-ion.dtsi"
#include "msmfalcon-bus.dtsi"
+#include "msm-pmfalcon-rpm-regulator.dtsi"
+#include "msm-pm2falcon-rpm-regulator.dtsi"
#include "msmfalcon-regulator.dtsi"
#include "msm-gdsc-falcon.dtsi"
diff --git a/arch/arm/boot/dts/qcom/msmtriton-regulator.dtsi b/arch/arm/boot/dts/qcom/msmtriton-regulator.dtsi
index a30a65a32d0a..323024278406 100644
--- a/arch/arm/boot/dts/qcom/msmtriton-regulator.dtsi
+++ b/arch/arm/boot/dts/qcom/msmtriton-regulator.dtsi
@@ -14,343 +14,343 @@
/ {
/* PMFALCON S1 - VDD_APC0 supply */
- pmfalcon_s1a: regulator-pmfalcon-s1a {
+ pmfalcon_s1: regulator-pmfalcon-s1 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s1a";
+ regulator-name = "pmfalcon_s1";
qcom,hpm-min-load = <100000>;
regulator-min-microvolt = <565000>;
regulator-max-microvolt = <1170000>;
};
/* PMFALCON S2 + S3 = VDD_APC1 supply */
- pmfalcon_s2a: regulator-pmfalcon-s2a {
+ pmfalcon_s2: regulator-pmfalcon-s2 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s2a";
+ regulator-name = "pmfalcon_s2";
qcom,hpm-min-load = <100000>;
regulator-min-microvolt = <565000>;
regulator-max-microvolt = <1170000>;
};
- pmfalcon_s4a: regulator-pmfalcon-s4a {
+ pmfalcon_s4: regulator-pmfalcon-s4 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s4a";
+ regulator-name = "pmfalcon_s4";
qcom,hpm-min-load = <100000>;
regulator-min-microvolt = <1805000>;
regulator-max-microvolt = <2040000>;
};
- pmfalcon_s5a: regulator-pmfalcon-s5a {
+ pmfalcon_s5: regulator-pmfalcon-s5 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s5a";
+ regulator-name = "pmfalcon_s5";
qcom,hpm-min-load = <100000>;
regulator-min-microvolt = <1350000>;
regulator-max-microvolt = <1350000>;
};
- pmfalcon_s6a: regulator-pmfalcon-s6a {
+ pmfalcon_s6: regulator-pmfalcon-s6 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s6a";
+ regulator-name = "pmfalcon_s6";
qcom,hpm-min-load = <100000>;
regulator-min-microvolt = <504000>;
regulator-max-microvolt = <992000>;
};
- pmfalcon_s1b: regulator-pmfalcon-s1b {
+ pm2falcon_s1: regulator-pm2falcon-s1 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s1b";
+ regulator-name = "pm2falcon_s1";
qcom,hpm-min-load = <100000>;
regulator-min-microvolt = <1125000>;
regulator-max-microvolt = <1125000>;
};
- pmfalcon_s2b: regulator-pmfalcon-s2b {
+ pm2falcon_s2: regulator-pm2falcon-s2 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s2b";
+ regulator-name = "pm2falcon_s2";
qcom,hpm-min-load = <100000>;
regulator-min-microvolt = <1050000>;
regulator-max-microvolt = <1050000>;
};
/* PMFALCON S3 + S4 - VDD_CX supply */
- pmfalcon_s3b_level: regulator-pmfalcon-s3b-level {
+ pm2falcon_s3_level: regulator-pm2falcon-s3-level {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s3b_level";
+ regulator-name = "pm2falcon_s3_level";
qcom,hpm-min-load = <100000>;
regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
};
- pmfalcon_s3b_floor_level: regulator-pmfalcon-s3b-floor-level {
+ pm2falcon_s3_floor_level: regulator-pm2falcon-s3-floor-level {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s3b_floor_level";
+ regulator-name = "pm2falcon_s3_floor_level";
qcom,hpm-min-load = <100000>;
regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
};
- pmfalcon_s3b_level_ao: regulator-pmfalcon-s3b-level-ao {
+ pm2falcon_s3_level_ao: regulator-pm2falcon-s3-level-ao {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s3b_level_ao";
+ regulator-name = "pm2falcon_s3_level_ao";
qcom,hpm-min-load = <100000>;
regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
};
/* PMFALCON S5 - VDD_MX supply */
- pmfalcon_s5b_level: regulator-pmfalcon-s5b-level {
+ pm2falcon_s5_level: regulator-pm2falcon-s5-level {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s5b_level";
+ regulator-name = "pm2falcon_s5_level";
qcom,hpm-min-load = <100000>;
regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
};
- pmfalcon_s5b_floor_level: regulator-pmfalcon-s5b-floor-level {
+ pm2falcon_s5_floor_level: regulator-pm2falcon-s5-floor-level {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s5b_floor_level";
+ regulator-name = "pm2falcon_s5_floor_level";
qcom,hpm-min-load = <100000>;
regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
};
- pmfalcon_s5b_level_ao: regulator-pmfalcon-s5b-level-ao {
+ pm2falcon_s5_level_ao: regulator-pm2falcon-s5-level-ao {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_s5b_level_ao";
+ regulator-name = "pm2falcon_s5_level_ao";
qcom,hpm-min-load = <100000>;
regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
};
- pmfalcon_l1a: regulator-pmfalcon-l1a {
+ pmfalcon_l1: regulator-pmfalcon-l1 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l1a";
+ regulator-name = "pmfalcon_l1";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <1150000>;
regulator-max-microvolt = <1250000>;
};
- pmfalcon_l2a: regulator-pmfalcon-l2a {
+ pmfalcon_l2: regulator-pmfalcon-l2 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l2a";
+ regulator-name = "pmfalcon_l2";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1010000>;
};
- pmfalcon_l3a: regulator-pmfalcon-l3a {
+ pmfalcon_l3: regulator-pmfalcon-l3 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l3a";
+ regulator-name = "pmfalcon_l3";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1010000>;
};
/* TODO: remove if ADRASTEA CX/MX not voted from APPS */
- pmfalcon_l5a: regulator-pmfalcon-l5a {
+ pmfalcon_l5: regulator-pmfalcon-l5 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l5a";
+ regulator-name = "pmfalcon_l5";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <525000>;
regulator-max-microvolt = <950000>;
};
- pmfalcon_l6a: regulator-pmfalcon-l6a {
+ pmfalcon_l6: regulator-pmfalcon-l6 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l6a";
+ regulator-name = "pmfalcon_l6";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1370000>;
};
- pmfalcon_l7a: regulator-pmfalcon-l7a {
+ pmfalcon_l7: regulator-pmfalcon-l7 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l7a";
+ regulator-name = "pmfalcon_l7";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
};
- pmfalcon_l8a: regulator-pmfalcon-l8a {
+ pmfalcon_l8: regulator-pmfalcon-l8 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l8a";
+ regulator-name = "pmfalcon_l8";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <1750000>;
regulator-max-microvolt = <1900000>;
};
- pmfalcon_l9a: regulator-pmfalcon-l9a {
+ pmfalcon_l9: regulator-pmfalcon-l9 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l9a";
+ regulator-name = "pmfalcon_l9";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <1750000>;
regulator-max-microvolt = <1900000>;
};
- pmfalcon_l10a: regulator-pmfalcon-l10a {
+ pmfalcon_l10: regulator-pmfalcon-l10 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l10a";
+ regulator-name = "pmfalcon_l10";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <1780000>;
regulator-max-microvolt = <1950000>;
};
- pmfalcon_l11a: regulator-pmfalcon-l11a {
+ pmfalcon_l11: regulator-pmfalcon-l11 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l11a";
+ regulator-name = "pmfalcon_l11";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <1780000>;
regulator-max-microvolt = <1950000>;
};
- pmfalcon_l12a: regulator-pmfalcon-l12a {
+ pmfalcon_l12: regulator-pmfalcon-l12 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l12a";
+ regulator-name = "pmfalcon_l12";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <1780000>;
regulator-max-microvolt = <1950000>;
};
- pmfalcon_l13a: regulator-pmfalcon-l13a {
+ pmfalcon_l13: regulator-pmfalcon-l13 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l13a";
+ regulator-name = "pmfalcon_l13";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <1750000>;
regulator-max-microvolt = <1950000>;
};
- pmfalcon_l14a: regulator-pmfalcon-l14a {
+ pmfalcon_l14: regulator-pmfalcon-l14 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l14a";
+ regulator-name = "pmfalcon_l14";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <1710000>;
regulator-max-microvolt = <1900000>;
};
- pmfalcon_l15a: regulator-pmfalcon-l15a {
+ pmfalcon_l15: regulator-pmfalcon-l15 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l15a";
+ regulator-name = "pmfalcon_l15";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <1650000>;
regulator-max-microvolt = <2950000>;
};
- pmfalcon_l17a: regulator-pmfalcon-l17a {
+ pmfalcon_l17: regulator-pmfalcon-l17 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l17a";
+ regulator-name = "pmfalcon_l17";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <1650000>;
regulator-max-microvolt = <2950000>;
};
- pmfalcon_l19a: regulator-pmfalcon-l19a {
+ pmfalcon_l19: regulator-pmfalcon-l19 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l19a";
+ regulator-name = "pmfalcon_l19";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <3200000>;
regulator-max-microvolt = <3400000>;
};
- pmfalcon_l1b: regulator-pmfalcon-l1b {
+ pm2falcon_l1: regulator-pm2falcon-l1 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l1b";
+ regulator-name = "pm2falcon_l1";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <925000>;
};
- pmfalcon_l2b: regulator-pmfalcon-l2b {
+ pm2falcon_l2: regulator-pm2falcon-l2 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l2b";
+ regulator-name = "pm2falcon_l2";
qcom,hpm-min-load = <5000>;
regulator-min-microvolt = <350000>;
regulator-max-microvolt = <3100000>;
};
- pmfalcon_l3b: regulator-pmfalcon-l3b {
+ pm2falcon_l3: regulator-pm2falcon-l3 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l3b";
+ regulator-name = "pm2falcon_l3";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <1710000>;
regulator-max-microvolt = <3600000>;
};
- pmfalcon_l4b: regulator-pmfalcon-l4b {
+ pm2falcon_l4: regulator-pm2falcon-l4 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l4b";
+ regulator-name = "pm2falcon_l4";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <2950000>;
};
- pmfalcon_l5b: regulator-pmfalcon-l5b {
+ pm2falcon_l5: regulator-pm2falcon-l5 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l5b";
+ regulator-name = "pm2falcon_l5";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <1721000>;
regulator-max-microvolt = <3600000>;
};
- pmfalcon_l6b: regulator-pmfalcon-l6b {
+ pm2falcon_l6: regulator-pm2falcon-l6 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l6b";
+ regulator-name = "pm2falcon_l6";
qcom,hpm-min-load = <5000>;
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <3300000>;
};
- pmfalcon_l7b: regulator-pmfalcon-l7b {
+ pm2falcon_l7: regulator-pm2falcon-l7 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l7b";
+ regulator-name = "pm2falcon_l7";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3125000>;
};
- pmfalcon_l8b: regulator-pmfalcon-l8b {
+ pm2falcon_l8: regulator-pm2falcon-l8 {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l8b";
+ regulator-name = "pm2falcon_l8";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <3200000>;
regulator-max-microvolt = <3400000>;
};
/* PMFALCON L9 = VDD_SSC_CX supply */
- pmfalcon_l9b_level: regulator-pmfalcon-l9b-level {
+ pm2falcon_l9_level: regulator-pm2falcon-l9-level {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l9b_level";
+ regulator-name = "pm2falcon_l9_level";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
};
- pmfalcon_l9b_floor_level: regulator-pmfalcon-l9b-floor-level {
+ pm2falcon_l9_floor_level: regulator-pm2falcon-l9-floor-level {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l9b_floor_level";
+ regulator-name = "pm2falcon_l9_floor_level";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
};
/* PMFALCON L10 = VDD_SSC_MX supply */
- pmfalcon_l10b_level: regulator-pmfalcon-l10b-level {
+ pm2falcon_l10_level: regulator-pm2falcon-l10-level {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l10b_level";
+ regulator-name = "pm2falcon_l10_level";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
};
- pmfalcon_l10b_floor_level: regulator-pmfalcon-l10b-floor-level {
+ pm2falcon_l10_floor_level: regulator-pm2falcon-l10-floor-level {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_l10b_floor_level";
+ regulator-name = "pm2falcon_l10_floor_level";
qcom,hpm-min-load = <10000>;
regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
regulator-max-microvolt = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
};
- pmfalcon_bobb: regulator-pmfalcon-bob {
+ pm2falcon_bob: regulator-pm2falcon-bob {
compatible = "qcom,stub-regulator";
- regulator-name = "pmfalcon_bob";
+ regulator-name = "pm2falcon_bob";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
diff --git a/arch/arm/boot/dts/qcom/msmtriton-rumi.dts b/arch/arm/boot/dts/qcom/msmtriton-rumi.dts
index d3c62dbf99f2..0317c35d1f44 100644
--- a/arch/arm/boot/dts/qcom/msmtriton-rumi.dts
+++ b/arch/arm/boot/dts/qcom/msmtriton-rumi.dts
@@ -27,3 +27,8 @@
pinctrl-names = "default";
pinctrl-0 = <&uart_console_active>;
};
+
+&clock_gcc {
+ compatible = "qcom,dummycc";
+ clock-output-names = "gcc_clocks";
+};
diff --git a/arch/arm/boot/dts/qcom/msmtriton.dtsi b/arch/arm/boot/dts/qcom/msmtriton.dtsi
index 281b3f51ba11..06f296a49113 100644
--- a/arch/arm/boot/dts/qcom/msmtriton.dtsi
+++ b/arch/arm/boot/dts/qcom/msmtriton.dtsi
@@ -246,6 +246,32 @@
qcom,pipe-attr-ee;
};
+ qcom,memshare {
+ compatible = "qcom,memshare";
+
+ qcom,client_1 {
+ compatible = "qcom,memshare-peripheral";
+ qcom,peripheral-size = <0x200000>;
+ qcom,client-id = <0>;
+ qcom,allocate-boot-time;
+ label = "modem";
+ };
+
+ qcom,client_2 {
+ compatible = "qcom,memshare-peripheral";
+ qcom,peripheral-size = <0x300000>;
+ qcom,client-id = <2>;
+ label = "modem";
+ };
+
+ mem_client_3_size: qcom,client_3 {
+ compatible = "qcom,memshare-peripheral";
+ qcom,peripheral-size = <0x0>;
+ qcom,client-id = <1>;
+ label = "modem";
+ };
+ };
+
tsens: tsens@10ad000 {
compatible = "qcom,msmtriton-tsens";
reg = <0x10ad000 0x2000>;
@@ -340,8 +366,10 @@
};
clock_gcc: clock-controller@100000 {
- compatible = "qcom,dummycc";
- clock-output-names = "gcc_clocks";
+ compatible = "qcom,gcc-msmfalcon";
+ reg = <0x100000 0x94000>;
+ vdd_dig-supply = <&pm2falcon_s3_level>;
+ vdd_dig_ao-supply = <&pm2falcon_s3_level_ao>;
#clock-cells = <1>;
#reset-cells = <1>;
};
@@ -503,6 +531,13 @@
qcom,xprt = "smem";
};
+ rpm_bus: qcom,rpm-smd {
+ compatible = "qcom,rpm-glink";
+ qcom,glink-edge = "rpm";
+ rpm-channel-name = "rpm_requests";
+ rpm-standalone;
+ };
+
qcom,ipc_router {
compatible = "qcom,ipc_router";
qcom,node-id = <1>;
@@ -554,7 +589,7 @@
reg = <0x15700000 0x00100>;
interrupts = <0 162 1>;
- vdd_cx-supply = <&pmfalcon_s3b_level>;
+ vdd_cx-supply = <&pm2falcon_s3_level>;
qcom,proxy-reg-names = "vdd_cx";
qcom,vdd_cx-uV-uA = <RPM_SMD_REGULATOR_LEVEL_TURBO 100000>;
@@ -638,9 +673,9 @@
"mnoc_axi_clk";
interrupts = <0 448 1>;
- vdd_cx-supply = <&pmfalcon_s3b_level>;
+ vdd_cx-supply = <&pm2falcon_s3_level>;
vdd_cx-voltage = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
- vdd_mx-supply = <&pmfalcon_s5b_level>;
+ vdd_mx-supply = <&pm2falcon_s5_level>;
vdd_mx-uV = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
qcom,firmware-name = "modem";
qcom,pil-self-auth;
@@ -662,6 +697,19 @@
qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
status = "ok";
};
+
+ qcom,msm-imem@146bf000 {
+ compatible = "qcom,msm-imem";
+ reg = <0x146bf000 0x1000>;
+ ranges = <0x0 0x146bf000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pil@94c {
+ compatible = "qcom,msm-imem-pil";
+ reg = <0x94c 200>;
+ };
+ };
};
#include "msmtriton-ion.dtsi"
diff --git a/arch/arm/configs/msmcortex_defconfig b/arch/arm/configs/msmcortex_defconfig
index 8be2b187a524..f8743e760054 100644
--- a/arch/arm/configs/msmcortex_defconfig
+++ b/arch/arm/configs/msmcortex_defconfig
@@ -27,6 +27,7 @@ CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_ARCH_MMAP_RND_BITS=16
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
@@ -440,6 +441,7 @@ CONFIG_MSM_GLINK_PKT=y
CONFIG_MSM_SPM=y
CONFIG_QCOM_SCM=y
CONFIG_QCOM_WATCHDOG_V2=y
+CONFIG_QCOM_IRQ_HELPER=y
CONFIG_QCOM_MEMORY_DUMP_V2=y
CONFIG_ICNSS=y
CONFIG_ICNSS_DEBUG=y
diff --git a/arch/arm/configs/msmfalcon_defconfig b/arch/arm/configs/msmfalcon_defconfig
index 085f6242b616..511b9fe32b9b 100644
--- a/arch/arm/configs/msmfalcon_defconfig
+++ b/arch/arm/configs/msmfalcon_defconfig
@@ -451,6 +451,7 @@ CONFIG_MSM_GLINK_PKT=y
CONFIG_MSM_SPM=y
CONFIG_QCOM_SCM=y
CONFIG_QCOM_WATCHDOG_V2=y
+CONFIG_QCOM_IRQ_HELPER=y
CONFIG_QCOM_MEMORY_DUMP_V2=y
CONFIG_ICNSS=y
CONFIG_ICNSS_DEBUG=y
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 52486c0e6598..80c4c50814d8 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -807,6 +807,7 @@ static void arm_dma_unremap(struct device *dev, void *remapped_addr,
unsigned int flags = VM_ARM_DMA_CONSISTENT | VM_USERMAP;
struct vm_struct *area;
+ size = PAGE_ALIGN(size);
remapped_addr = (void *)((unsigned long)remapped_addr & PAGE_MASK);
area = find_vm_area(remapped_addr);
@@ -1818,7 +1819,7 @@ void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
total_length = PAGE_ALIGN((iova & ~PAGE_MASK) + total_length);
iova &= PAGE_MASK;
- iommu_unmap_range(mapping->domain, iova, total_length);
+ iommu_unmap(mapping->domain, iova, total_length);
__free_iova(mapping, iova, total_length);
}
diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig
index 5f8b02904d49..520a60c46106 100644
--- a/arch/arm64/configs/msm-perf_defconfig
+++ b/arch/arm64/configs/msm-perf_defconfig
@@ -32,6 +32,7 @@ CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig
index c1c0ae9da001..6249b604466b 100644
--- a/arch/arm64/configs/msm_defconfig
+++ b/arch/arm64/configs/msm_defconfig
@@ -29,6 +29,7 @@ CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig
index bf63a360eb06..3990bece1dd1 100644
--- a/arch/arm64/configs/msmcortex-perf_defconfig
+++ b/arch/arm64/configs/msmcortex-perf_defconfig
@@ -35,6 +35,7 @@ CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
@@ -249,6 +250,8 @@ CONFIG_DM_CRYPT=y
CONFIG_DM_REQ_CRYPT=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
+CONFIG_DM_VERITY_FEC=y
+CONFIG_DM_ANDROID_VERITY=y
CONFIG_NETDEVICES=y
CONFIG_BONDING=y
CONFIG_DUMMY=y
diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig
index 93dbc4f7e52f..15ca50859eca 100644
--- a/arch/arm64/configs/msmcortex_defconfig
+++ b/arch/arm64/configs/msmcortex_defconfig
@@ -34,6 +34,7 @@ CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
@@ -251,6 +252,8 @@ CONFIG_DM_CRYPT=y
CONFIG_DM_REQ_CRYPT=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
+CONFIG_DM_VERITY_FEC=y
+CONFIG_DM_ANDROID_VERITY=y
CONFIG_NETDEVICES=y
CONFIG_BONDING=y
CONFIG_DUMMY=y
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 07c67348b815..df083e9350c4 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -455,6 +455,7 @@ static void arm64_dma_unremap(struct device *dev, void *remapped_addr,
{
struct vm_struct *area;
+ size = PAGE_ALIGN(size);
remapped_addr = (void *)((unsigned long)remapped_addr & PAGE_MASK);
area = find_vm_area(remapped_addr);
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index a5781f6db269..9d0955289796 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -3434,9 +3434,6 @@ static int __init diagchar_init(void)
ret = diagfwd_init();
if (ret)
goto fail;
- ret = diagfwd_bridge_init();
- if (ret)
- goto fail;
ret = diagfwd_cntl_init();
if (ret)
goto fail;
@@ -3467,6 +3464,9 @@ static int __init diagchar_init(void)
goto fail;
pr_debug("diagchar initialized now");
+ ret = diagfwd_bridge_init();
+ if (ret)
+ diagfwd_bridge_exit();
return 0;
fail:
@@ -3482,6 +3482,7 @@ fail:
diag_masks_exit();
diag_remote_exit();
return -1;
+
}
static void diagchar_exit(void)
diff --git a/drivers/char/diag/diagfwd_glink.c b/drivers/char/diag/diagfwd_glink.c
index a2ffabe43c86..ce523ac35a51 100644
--- a/drivers/char/diag/diagfwd_glink.c
+++ b/drivers/char/diag/diagfwd_glink.c
@@ -455,6 +455,8 @@ static void diag_glink_transport_notify_state(void *handle, const void *priv,
"%s received channel remote disconnect for periph:%d\n",
glink_info->name, glink_info->peripheral);
atomic_set(&glink_info->opened, 0);
+ diagfwd_channel_close(glink_info->fwd_ctxt);
+ atomic_set(&glink_info->tx_intent_ready, 0);
break;
default:
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
@@ -501,6 +503,7 @@ static void diag_glink_close_work_fn(struct work_struct *work)
glink_close(glink_info->hdl);
atomic_set(&glink_info->opened, 0);
+ atomic_set(&glink_info->tx_intent_ready, 0);
glink_info->hdl = NULL;
diagfwd_channel_close(glink_info->fwd_ctxt);
}
diff --git a/drivers/char/diag/diagfwd_mhi.c b/drivers/char/diag/diagfwd_mhi.c
index f7b1e98f22b0..df26e2522baf 100644
--- a/drivers/char/diag/diagfwd_mhi.c
+++ b/drivers/char/diag/diagfwd_mhi.c
@@ -49,6 +49,7 @@ struct diag_mhi_info diag_mhi[NUM_MHI_DEV] = {
.enabled = 0,
.num_read = 0,
.mempool = POOL_TYPE_MDM,
+ .mempool_init = 0,
.mhi_wq = NULL,
.read_ch = {
.chan = MHI_CLIENT_DIAG_IN,
@@ -68,6 +69,7 @@ struct diag_mhi_info diag_mhi[NUM_MHI_DEV] = {
.enabled = 0,
.num_read = 0,
.mempool = POOL_TYPE_MDM_DCI,
+ .mempool_init = 0,
.mhi_wq = NULL,
.read_ch = {
.chan = MHI_CLIENT_DCI_IN,
@@ -684,6 +686,7 @@ int diag_mhi_init()
strlcpy(wq_name, "diag_mhi_", DIAG_MHI_STRING_SZ);
strlcat(wq_name, mhi_info->name, sizeof(mhi_info->name));
diagmem_init(driver, mhi_info->mempool);
+ mhi_info->mempool_init = 1;
mhi_info->mhi_wq = create_singlethread_workqueue(wq_name);
if (!mhi_info->mhi_wq)
goto fail;
@@ -725,7 +728,8 @@ void diag_mhi_exit()
if (mhi_info->mhi_wq)
destroy_workqueue(mhi_info->mhi_wq);
mhi_close(mhi_info->id);
- diagmem_exit(driver, mhi_info->mempool);
+ if (mhi_info->mempool_init)
+ diagmem_exit(driver, mhi_info->mempool);
}
}
diff --git a/drivers/char/diag/diagfwd_mhi.h b/drivers/char/diag/diagfwd_mhi.h
index 8332efdf5efb..a4466977ca97 100644
--- a/drivers/char/diag/diagfwd_mhi.h
+++ b/drivers/char/diag/diagfwd_mhi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 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
@@ -65,6 +65,7 @@ struct diag_mhi_info {
int id;
int dev_id;
int mempool;
+ int mempool_init;
int num_read;
uint8_t enabled;
char name[DIAG_MHI_NAME_SZ];
diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c
index 40fdcbaaf31a..c78a5f4fbe74 100644
--- a/drivers/char/diag/diagfwd_peripheral.c
+++ b/drivers/char/diag/diagfwd_peripheral.c
@@ -438,6 +438,7 @@ int diagfwd_peripheral_init(void)
fwd_info->read_bytes = 0;
fwd_info->write_bytes = 0;
spin_lock_init(&fwd_info->buf_lock);
+ spin_lock_init(&fwd_info->write_buf_lock);
mutex_init(&fwd_info->data_mutex);
}
}
@@ -453,6 +454,7 @@ int diagfwd_peripheral_init(void)
fwd_info->read_bytes = 0;
fwd_info->write_bytes = 0;
spin_lock_init(&fwd_info->buf_lock);
+ spin_lock_init(&fwd_info->write_buf_lock);
mutex_init(&fwd_info->data_mutex);
/*
* This state shouldn't be set for Control channels
@@ -686,16 +688,19 @@ void *diagfwd_request_write_buf(struct diagfwd_info *fwd_info)
{
void *buf = NULL;
int index;
+ unsigned long flags;
+ spin_lock_irqsave(&fwd_info->write_buf_lock, flags);
for (index = 0 ; index < NUM_WRITE_BUFFERS; index++) {
if (!atomic_read(&(fwd_info->buf_ptr[index]->in_busy))) {
+ atomic_set(&(fwd_info->buf_ptr[index]->in_busy), 1);
buf = fwd_info->buf_ptr[index]->data;
if (!buf)
return NULL;
- atomic_set(&(fwd_info->buf_ptr[index]->in_busy), 1);
break;
}
}
+ spin_unlock_irqrestore(&fwd_info->write_buf_lock, flags);
return buf;
}
@@ -760,7 +765,6 @@ int diagfwd_write(uint8_t peripheral, uint8_t type, void *buf, int len)
static void __diag_fwd_open(struct diagfwd_info *fwd_info)
{
- int i;
if (!fwd_info)
return;
@@ -775,10 +779,7 @@ static void __diag_fwd_open(struct diagfwd_info *fwd_info)
if (fwd_info->p_ops && fwd_info->p_ops->open)
fwd_info->p_ops->open(fwd_info->ctxt);
- for (i = 0; i < NUM_WRITE_BUFFERS; i++) {
- if (fwd_info->buf_ptr[i])
- atomic_set(&fwd_info->buf_ptr[i]->in_busy, 0);
- }
+
diagfwd_queue_read(fwd_info);
}
@@ -839,6 +840,7 @@ void diagfwd_close(uint8_t peripheral, uint8_t type)
int diagfwd_channel_open(struct diagfwd_info *fwd_info)
{
+ int i;
if (!fwd_info)
return -EIO;
@@ -859,6 +861,10 @@ int diagfwd_channel_open(struct diagfwd_info *fwd_info)
diagfwd_write_buffers_init(fwd_info);
if (fwd_info && fwd_info->c_ops && fwd_info->c_ops->open)
fwd_info->c_ops->open(fwd_info);
+ for (i = 0; i < NUM_WRITE_BUFFERS; i++) {
+ if (fwd_info->buf_ptr[i])
+ atomic_set(&fwd_info->buf_ptr[i]->in_busy, 0);
+ }
diagfwd_queue_read(fwd_info);
DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "p: %d t: %d considered opened\n",
fwd_info->peripheral, fwd_info->type);
@@ -873,6 +879,7 @@ int diagfwd_channel_open(struct diagfwd_info *fwd_info)
int diagfwd_channel_close(struct diagfwd_info *fwd_info)
{
+ int i;
if (!fwd_info)
return -EIO;
@@ -885,6 +892,10 @@ int diagfwd_channel_close(struct diagfwd_info *fwd_info)
if (fwd_info->buf_2 && fwd_info->buf_2->data)
atomic_set(&fwd_info->buf_2->in_busy, 0);
+ for (i = 0; i < NUM_WRITE_BUFFERS; i++) {
+ if (fwd_info->buf_ptr[i])
+ atomic_set(&fwd_info->buf_ptr[i]->in_busy, 1);
+ }
DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "p: %d t: %d considered closed\n",
fwd_info->peripheral, fwd_info->type);
@@ -940,10 +951,11 @@ int diagfwd_write_buffer_done(struct diagfwd_info *fwd_info, const void *ptr)
int found = 0;
int index = 0;
+ unsigned long flags;
if (!fwd_info || !ptr)
return found;
-
+ spin_lock_irqsave(&fwd_info->write_buf_lock, flags);
for (index = 0; index < NUM_WRITE_BUFFERS; index++) {
if (fwd_info->buf_ptr[index]->data == ptr) {
atomic_set(&fwd_info->buf_ptr[index]->in_busy, 0);
@@ -951,6 +963,7 @@ int diagfwd_write_buffer_done(struct diagfwd_info *fwd_info, const void *ptr)
break;
}
}
+ spin_unlock_irqrestore(&fwd_info->write_buf_lock, flags);
return found;
}
@@ -1197,7 +1210,7 @@ void diagfwd_write_buffers_init(struct diagfwd_info *fwd_info)
return;
}
- spin_lock_irqsave(&fwd_info->buf_lock, flags);
+ spin_lock_irqsave(&fwd_info->write_buf_lock, flags);
for (i = 0; i < NUM_WRITE_BUFFERS; i++) {
if (!fwd_info->buf_ptr[i])
fwd_info->buf_ptr[i] =
@@ -1215,11 +1228,11 @@ void diagfwd_write_buffers_init(struct diagfwd_info *fwd_info)
kmemleak_not_leak(fwd_info->buf_ptr[i]->data);
}
}
- spin_unlock_irqrestore(&fwd_info->buf_lock, flags);
+ spin_unlock_irqrestore(&fwd_info->write_buf_lock, flags);
return;
err:
- spin_unlock_irqrestore(&fwd_info->buf_lock, flags);
+ spin_unlock_irqrestore(&fwd_info->write_buf_lock, flags);
pr_err("diag:unable to allocate write buffers\n");
diagfwd_write_buffers_exit(fwd_info);
@@ -1233,7 +1246,7 @@ static void diagfwd_write_buffers_exit(struct diagfwd_info *fwd_info)
if (!fwd_info)
return;
- spin_lock_irqsave(&fwd_info->buf_lock, flags);
+ spin_lock_irqsave(&fwd_info->write_buf_lock, flags);
for (i = 0; i < NUM_WRITE_BUFFERS; i++) {
if (fwd_info->buf_ptr[i]) {
kfree(fwd_info->buf_ptr[i]->data);
@@ -1242,5 +1255,5 @@ static void diagfwd_write_buffers_exit(struct diagfwd_info *fwd_info)
fwd_info->buf_ptr[i] = NULL;
}
}
- spin_unlock_irqrestore(&fwd_info->buf_lock, flags);
+ spin_unlock_irqrestore(&fwd_info->write_buf_lock, flags);
}
diff --git a/drivers/char/diag/diagfwd_peripheral.h b/drivers/char/diag/diagfwd_peripheral.h
index b511bf495bc2..cbbab86a9425 100644
--- a/drivers/char/diag/diagfwd_peripheral.h
+++ b/drivers/char/diag/diagfwd_peripheral.h
@@ -71,6 +71,7 @@ struct diagfwd_info {
unsigned long read_bytes;
unsigned long write_bytes;
spinlock_t buf_lock;
+ spinlock_t write_buf_lock;
struct mutex data_mutex;
void *ctxt;
struct diagfwd_buf_t *buf_1;
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 1eb6e32e0d51..25ab30063072 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2267,6 +2267,7 @@ EXPORT_SYMBOL_GPL(clk_set_flags);
static struct dentry *rootdir;
static int inited = 0;
+static u32 debug_suspend;
static DEFINE_MUTEX(clk_debug_lock);
static HLIST_HEAD(clk_debug_list);
@@ -2409,6 +2410,309 @@ static const struct file_operations clk_dump_fops = {
.release = single_release,
};
+static int clock_debug_rate_set(void *data, u64 val)
+{
+ struct clk_core *core = data;
+ int ret;
+
+ ret = clk_set_rate(core->hw->clk, val);
+ if (ret)
+ pr_err("clk_set_rate(%lu) failed (%d)\n",
+ (unsigned long)val, ret);
+
+ return ret;
+}
+
+static int clock_debug_rate_get(void *data, u64 *val)
+{
+ struct clk_core *core = data;
+
+ *val = core->hw->core->rate;
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_debug_rate_get,
+ clock_debug_rate_set, "%llu\n");
+
+static ssize_t clock_parent_read(struct file *filp, char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ char name[256] = {0};
+ struct clk_core *core = filp->private_data;
+ struct clk_core *p = core->hw->core->parent;
+
+ snprintf(name, sizeof(name), "%s\n", p ? p->name : "None\n");
+
+ return simple_read_from_buffer(ubuf, cnt, ppos, name, strlen(name));
+}
+
+static const struct file_operations clock_parent_fops = {
+ .open = simple_open,
+ .read = clock_parent_read,
+};
+
+static int clock_debug_enable_set(void *data, u64 val)
+{
+ struct clk_core *core = data;
+ int rc = 0;
+
+ if (val)
+ rc = clk_prepare_enable(core->hw->clk);
+ else
+ clk_disable_unprepare(core->hw->clk);
+
+ return rc;
+}
+
+static int clock_debug_enable_get(void *data, u64 *val)
+{
+ struct clk_core *core = data;
+ int enabled = 0;
+
+ enabled = core->enable_count;
+
+ *val = enabled;
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(clock_enable_fops, clock_debug_enable_get,
+ clock_debug_enable_set, "%lld\n");
+
+#define clock_debug_output(m, c, fmt, ...) \
+do { \
+ if (m) \
+ seq_printf(m, fmt, ##__VA_ARGS__); \
+ else if (c) \
+ pr_cont(fmt, ##__VA_ARGS__); \
+ else \
+ pr_info(fmt, ##__VA_ARGS__); \
+} while (0)
+
+int clock_debug_print_clock(struct clk_core *c, struct seq_file *s)
+{
+ char *start = "";
+ struct clk *clk;
+
+ if (!c || !c->prepare_count)
+ return 0;
+
+ clk = c->hw->clk;
+
+ clock_debug_output(s, 0, "\t");
+
+ do {
+ if (clk->core->vdd_class)
+ clock_debug_output(s, 1, "%s%s:%u:%u [%ld, %d]", start,
+ clk->core->name,
+ clk->core->prepare_count,
+ clk->core->enable_count,
+ clk->core->rate,
+ clk_find_vdd_level(clk->core, clk->core->rate));
+ else
+ clock_debug_output(s, 1, "%s%s:%u:%u [%ld]", start,
+ clk->core->name,
+ clk->core->prepare_count,
+ clk->core->enable_count,
+ clk->core->rate);
+ start = " -> ";
+ } while ((clk = clk_get_parent(clk)));
+
+ clock_debug_output(s, 1, "\n");
+
+ return 1;
+}
+
+/*
+ * clock_debug_print_enabled_clocks() - Print names of enabled clocks
+ */
+static void clock_debug_print_enabled_clocks(struct seq_file *s)
+{
+ struct clk_core *core;
+ int cnt = 0;
+
+ clock_debug_output(s, 0, "Enabled clocks:\n");
+
+ mutex_lock(&clk_debug_lock);
+
+ hlist_for_each_entry(core, &clk_debug_list, debug_node)
+ cnt += clock_debug_print_clock(core, s);
+
+ mutex_unlock(&clk_debug_lock);
+
+ if (cnt)
+ clock_debug_output(s, 0, "Enabled clock count: %d\n", cnt);
+ else
+ clock_debug_output(s, 0, "No clocks enabled.\n");
+}
+
+static int enabled_clocks_show(struct seq_file *s, void *unused)
+{
+ clock_debug_print_enabled_clocks(s);
+
+ return 0;
+}
+
+static int enabled_clocks_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, enabled_clocks_show, inode->i_private);
+}
+
+static const struct file_operations clk_enabled_list_fops = {
+ .open = enabled_clocks_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static void clk_debug_print_hw(struct clk_core *clk, struct seq_file *f)
+{
+ if (IS_ERR_OR_NULL(clk))
+ return;
+
+ clk_debug_print_hw(clk->parent, f);
+
+ clock_debug_output(f, false, "%s\n", clk->name);
+
+ if (!clk->ops->list_registers)
+ return;
+
+ clk->ops->list_registers(f, clk->hw);
+}
+
+static int print_hw_show(struct seq_file *m, void *unused)
+{
+ struct clk_core *c = m->private;
+
+ clk_debug_print_hw(c, m);
+
+ return 0;
+}
+
+static int print_hw_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, print_hw_show, inode->i_private);
+}
+
+static const struct file_operations clock_print_hw_fops = {
+ .open = print_hw_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static int list_rates_show(struct seq_file *s, void *unused)
+{
+ struct clk_core *core = s->private;
+ int level = 0, i = 0;
+ unsigned long rate, rate_max = 0;
+
+ /* Find max frequency supported within voltage constraints. */
+ if (!core->vdd_class) {
+ rate_max = ULONG_MAX;
+ } else {
+ for (level = 0; level < core->num_rate_max; level++)
+ if (core->rate_max[level])
+ rate_max = core->rate_max[level];
+ }
+
+ /*
+ * List supported frequencies <= rate_max. Higher frequencies may
+ * appear in the frequency table, but are not valid and should not
+ * be listed.
+ */
+ while (!IS_ERR_VALUE(rate =
+ core->ops->list_rate(core->hw, i++, rate_max))) {
+ if (rate <= 0)
+ break;
+ if (rate <= rate_max)
+ seq_printf(s, "%lu\n", rate);
+ }
+
+ return 0;
+}
+
+static int list_rates_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, list_rates_show, inode->i_private);
+}
+
+static const struct file_operations list_rates_fops = {
+ .open = list_rates_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static void clock_print_rate_max_by_level(struct seq_file *s, int level)
+{
+ struct clk_core *core = s->private;
+ struct clk_vdd_class *vdd_class = core->vdd_class;
+ int off, i, vdd_level, nregs = vdd_class->num_regulators;
+
+ vdd_level = clk_find_vdd_level(core, core->rate);
+
+ seq_printf(s, "%2s%10lu", vdd_level == level ? "[" : "",
+ core->rate_max[level]);
+
+ for (i = 0; i < nregs; i++) {
+ off = nregs*level + i;
+ if (vdd_class->vdd_uv)
+ seq_printf(s, "%10u", vdd_class->vdd_uv[off]);
+ }
+
+ if (vdd_level == level)
+ seq_puts(s, "]");
+
+ seq_puts(s, "\n");
+}
+
+static int rate_max_show(struct seq_file *s, void *unused)
+{
+ struct clk_core *core = s->private;
+ struct clk_vdd_class *vdd_class = core->vdd_class;
+ int level = 0, i, nregs = vdd_class->num_regulators;
+ char reg_name[10];
+
+ int vdd_level = clk_find_vdd_level(core, core->rate);
+
+ if (vdd_level < 0) {
+ seq_printf(s, "could not find_vdd_level for %s, %ld\n",
+ core->name, core->rate);
+ return 0;
+ }
+
+ seq_printf(s, "%12s", "");
+ for (i = 0; i < nregs; i++) {
+ snprintf(reg_name, ARRAY_SIZE(reg_name), "reg %d", i);
+ seq_printf(s, "%10s", reg_name);
+ }
+
+ seq_printf(s, "\n%12s", "freq");
+ for (i = 0; i < nregs; i++)
+ seq_printf(s, "%10s", "uV");
+
+ seq_puts(s, "\n");
+
+ for (level = 0; level < core->num_rate_max; level++)
+ clock_print_rate_max_by_level(s, level);
+
+ return 0;
+}
+
+static int rate_max_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, rate_max_show, inode->i_private);
+}
+
+static const struct file_operations rate_max_fops = {
+ .open = rate_max_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
{
struct dentry *d;
@@ -2425,11 +2729,21 @@ static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
core->dentry = d;
- d = debugfs_create_u32("clk_rate", S_IRUGO, core->dentry,
- (u32 *)&core->rate);
+ d = debugfs_create_file("clk_rate", S_IRUGO, core->dentry, core,
+ &clock_rate_fops);
if (!d)
goto err_out;
+ if (core->ops->list_rate) {
+ if (!debugfs_create_file("clk_list_rates",
+ S_IRUGO, core->dentry, core, &list_rates_fops))
+ goto err_out;
+ }
+
+ if (core->vdd_class && !debugfs_create_file("clk_rate_max",
+ S_IRUGO, core->dentry, core, &rate_max_fops))
+ goto err_out;
+
d = debugfs_create_u32("clk_accuracy", S_IRUGO, core->dentry,
(u32 *)&core->accuracy);
if (!d)
@@ -2450,8 +2764,8 @@ static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
if (!d)
goto err_out;
- d = debugfs_create_u32("clk_enable_count", S_IRUGO, core->dentry,
- (u32 *)&core->enable_count);
+ d = debugfs_create_file("clk_enable_count", S_IRUGO, core->dentry,
+ core, &clock_enable_fops);
if (!d)
goto err_out;
@@ -2460,6 +2774,16 @@ static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
if (!d)
goto err_out;
+ d = debugfs_create_file("clk_parent", S_IRUGO, core->dentry, core,
+ &clock_parent_fops);
+ if (!d)
+ goto err_out;
+
+ d = debugfs_create_file("clk_print_regs", S_IRUGO, core->dentry,
+ core, &clock_print_hw_fops);
+ if (!d)
+ goto err_out;
+
if (core->ops->debug_init) {
ret = core->ops->debug_init(core->hw, core->dentry);
if (ret)
@@ -2531,6 +2855,19 @@ struct dentry *clk_debugfs_add_file(struct clk_hw *hw, char *name, umode_t mode,
}
EXPORT_SYMBOL_GPL(clk_debugfs_add_file);
+/*
+ * Print the names of all enabled clocks and their parents if
+ * debug_suspend is set from debugfs.
+ */
+void clock_debug_print_enabled(void)
+{
+ if (likely(!debug_suspend))
+ return;
+
+ clock_debug_print_enabled_clocks(NULL);
+}
+EXPORT_SYMBOL_GPL(clock_debug_print_enabled);
+
/**
* clk_debug_init - lazily populate the debugfs clk directory
*
@@ -2570,6 +2907,17 @@ static int __init clk_debug_init(void)
if (!d)
return -ENOMEM;
+ d = debugfs_create_file("clk_enabled_list", S_IRUGO, rootdir,
+ &clk_debug_list, &clk_enabled_list_fops);
+ if (!d)
+ return -ENOMEM;
+
+
+ d = debugfs_create_u32("debug_suspend", S_IRUGO | S_IWUSR,
+ rootdir, &debug_suspend);
+ if (!d)
+ return -ENOMEM;
+
mutex_lock(&clk_debug_lock);
hlist_for_each_entry(core, &clk_debug_list, debug_node)
clk_debug_create_one(core, rootdir);
diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h
index 97941b0f8f32..179b27c08022 100644
--- a/drivers/clk/clk.h
+++ b/drivers/clk/clk.h
@@ -20,6 +20,10 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
const char *con_id);
void __clk_free_clk(struct clk *clk);
+
+/* Debugfs API to print the enabled clocks */
+void clock_debug_print_enabled(void);
+
#else
/* All these casts to avoid ifdefs in clkdev... */
static inline struct clk *
diff --git a/drivers/clk/msm/clock-gpu-cobalt.c b/drivers/clk/msm/clock-gpu-cobalt.c
index 9d93351a083e..7cec9be1f42c 100644
--- a/drivers/clk/msm/clock-gpu-cobalt.c
+++ b/drivers/clk/msm/clock-gpu-cobalt.c
@@ -173,6 +173,7 @@ static struct clk_freq_tbl ftbl_gfx3d_clk_src_v2[] = {
F_SLEW( 515000000, 1030000000, gpu_pll0_pll_out_even, 1, 0, 0),
F_SLEW( 596000000, 1192000000, gpu_pll0_pll_out_even, 1, 0, 0),
F_SLEW( 670000000, 1340000000, gpu_pll0_pll_out_even, 1, 0, 0),
+ F_SLEW( 710000000, 1420000000, gpu_pll0_pll_out_even, 1, 0, 0),
F_END
};
@@ -611,7 +612,7 @@ static void msm_gfxcc_hamster_fixup(void)
static void msm_gfxcc_cobalt_v2_fixup(void)
{
- gpu_pll0_pll.c.fmax[VDD_DIG_MIN] = 1340000500;
+ gpu_pll0_pll.c.fmax[VDD_DIG_MIN] = 1420000500;
gfx3d_clk_src.freq_tbl = ftbl_gfx3d_clk_src_v2;
}
diff --git a/drivers/clk/msm/clock-mmss-cobalt.c b/drivers/clk/msm/clock-mmss-cobalt.c
index 9c1cdf967fb1..9e2a8fcab2a6 100644
--- a/drivers/clk/msm/clock-mmss-cobalt.c
+++ b/drivers/clk/msm/clock-mmss-cobalt.c
@@ -245,6 +245,7 @@ static struct rcg_clk ahb_clk_src = {
.c = {
.dbg_name = "ahb_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 40000000,
NOMINAL, 80800000),
CLK_INIT(ahb_clk_src.c),
@@ -277,6 +278,7 @@ static struct rcg_clk csi0_clk_src = {
.c = {
.dbg_name = "csi0_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP4(LOWER, 164571429, LOW, 256000000,
NOMINAL, 384000000, HIGH, 576000000),
CLK_INIT(csi0_clk_src.c),
@@ -315,6 +317,7 @@ static struct rcg_clk vfe0_clk_src = {
.c = {
.dbg_name = "vfe0_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP4(LOWER, 200000000, LOW, 384000000,
NOMINAL, 576000000, HIGH, 600000000),
CLK_INIT(vfe0_clk_src.c),
@@ -330,6 +333,7 @@ static struct rcg_clk vfe1_clk_src = {
.c = {
.dbg_name = "vfe1_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP4(LOWER, 200000000, LOW, 384000000,
NOMINAL, 576000000, HIGH, 600000000),
CLK_INIT(vfe1_clk_src.c),
@@ -358,6 +362,7 @@ static struct rcg_clk mdp_clk_src = {
.c = {
.dbg_name = "mdp_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP4(LOWER, 171430000, LOW, 275000000,
NOMINAL, 330000000, HIGH, 412500000),
CLK_INIT(mdp_clk_src.c),
@@ -382,6 +387,7 @@ static struct rcg_clk maxi_clk_src = {
.c = {
.dbg_name = "maxi_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP4(LOWER, 75000000, LOW, 171428571,
NOMINAL, 323200000, HIGH, 406000000),
CLK_INIT(maxi_clk_src.c),
@@ -416,6 +422,7 @@ static struct rcg_clk cpp_clk_src = {
.c = {
.dbg_name = "cpp_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP4(LOWER, 100000000, LOW, 200000000,
NOMINAL, 576000000, HIGH, 600000000),
CLK_INIT(cpp_clk_src.c),
@@ -446,6 +453,7 @@ static struct rcg_clk jpeg0_clk_src = {
.c = {
.dbg_name = "jpeg0_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 75000000, LOW, 150000000,
NOMINAL, 480000000),
CLK_INIT(jpeg0_clk_src.c),
@@ -469,6 +477,7 @@ static struct rcg_clk rot_clk_src = {
.c = {
.dbg_name = "rot_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP4(LOWER, 171430000, LOW, 275000000,
NOMINAL, 330000000, HIGH, 412500000),
CLK_INIT(rot_clk_src.c),
@@ -501,6 +510,7 @@ static struct rcg_clk video_core_clk_src = {
.c = {
.dbg_name = "video_core_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP4(LOWER, 100000000, LOW, 186000000,
NOMINAL, 360000000, HIGH, 465000000),
CLK_INIT(video_core_clk_src.c),
@@ -531,6 +541,7 @@ static struct rcg_clk csiphy_clk_src = {
.c = {
.dbg_name = "csiphy_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 164570000, LOW, 256000000,
NOMINAL, 384000000),
CLK_INIT(csiphy_clk_src.c),
@@ -546,6 +557,7 @@ static struct rcg_clk csi1_clk_src = {
.c = {
.dbg_name = "csi1_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP4(LOWER, 164570000, LOW, 256000000,
NOMINAL, 384000000, HIGH, 576000000),
CLK_INIT(csi1_clk_src.c),
@@ -561,6 +573,7 @@ static struct rcg_clk csi2_clk_src = {
.c = {
.dbg_name = "csi2_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP4(LOWER, 164570000, LOW, 256000000,
NOMINAL, 384000000, HIGH, 576000000),
CLK_INIT(csi2_clk_src.c),
@@ -576,6 +589,7 @@ static struct rcg_clk csi3_clk_src = {
.c = {
.dbg_name = "csi3_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP4(LOWER, 164570000, LOW, 256000000,
NOMINAL, 384000000, HIGH, 576000000),
CLK_INIT(csi3_clk_src.c),
@@ -607,6 +621,7 @@ static struct rcg_clk fd_core_clk_src = {
.c = {
.dbg_name = "fd_core_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 100000000, LOW, 200000000,
NOMINAL, 576000000),
CLK_INIT(fd_core_clk_src.c),
@@ -755,6 +770,7 @@ static struct rcg_clk video_subcore0_clk_src = {
.c = {
.dbg_name = "video_subcore0_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP4(LOWER, 100000000, LOW, 186000000,
NOMINAL, 360000000, HIGH, 465000000),
CLK_INIT(video_subcore0_clk_src.c),
@@ -771,6 +787,7 @@ static struct rcg_clk video_subcore1_clk_src = {
.c = {
.dbg_name = "video_subcore1_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP4(LOWER, 100000000, LOW, 186000000,
NOMINAL, 360000000, HIGH, 465000000),
CLK_INIT(video_subcore1_clk_src.c),
@@ -793,6 +810,7 @@ static struct rcg_clk cci_clk_src = {
.c = {
.dbg_name = "cci_clk_src",
.ops = &clk_ops_rcg_mnd,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 37500000, LOW, 50000000,
NOMINAL, 100000000),
CLK_INIT(cci_clk_src.c),
@@ -818,6 +836,7 @@ static struct rcg_clk camss_gp0_clk_src = {
.c = {
.dbg_name = "camss_gp0_clk_src",
.ops = &clk_ops_rcg_mnd,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 50000000, LOW, 100000000,
NOMINAL, 200000000),
CLK_INIT(camss_gp0_clk_src.c),
@@ -833,6 +852,7 @@ static struct rcg_clk camss_gp1_clk_src = {
.c = {
.dbg_name = "camss_gp1_clk_src",
.ops = &clk_ops_rcg_mnd,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 50000000, LOW, 100000000,
NOMINAL, 200000000),
CLK_INIT(camss_gp1_clk_src.c),
@@ -862,6 +882,7 @@ static struct rcg_clk mclk0_clk_src = {
.c = {
.dbg_name = "mclk0_clk_src",
.ops = &clk_ops_rcg_mnd,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 33333333, LOW, 66666667,
NOMINAL, 68571429),
CLK_INIT(mclk0_clk_src.c),
@@ -877,6 +898,7 @@ static struct rcg_clk mclk1_clk_src = {
.c = {
.dbg_name = "mclk1_clk_src",
.ops = &clk_ops_rcg_mnd,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 33333333, LOW, 66666667,
NOMINAL, 68571429),
CLK_INIT(mclk1_clk_src.c),
@@ -892,6 +914,7 @@ static struct rcg_clk mclk2_clk_src = {
.c = {
.dbg_name = "mclk2_clk_src",
.ops = &clk_ops_rcg_mnd,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 33333333, LOW, 66666667,
NOMINAL, 68571429),
CLK_INIT(mclk2_clk_src.c),
@@ -907,6 +930,7 @@ static struct rcg_clk mclk3_clk_src = {
.c = {
.dbg_name = "mclk3_clk_src",
.ops = &clk_ops_rcg_mnd,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 33333333, LOW, 66666667,
NOMINAL, 68571429),
CLK_INIT(mclk3_clk_src.c),
@@ -928,6 +952,7 @@ static struct rcg_clk csi0phytimer_clk_src = {
.c = {
.dbg_name = "csi0phytimer_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 100000000, LOW, 200000000,
NOMINAL, 269333333),
CLK_INIT(csi0phytimer_clk_src.c),
@@ -943,6 +968,7 @@ static struct rcg_clk csi1phytimer_clk_src = {
.c = {
.dbg_name = "csi1phytimer_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 100000000, LOW, 200000000,
NOMINAL, 269333333),
CLK_INIT(csi1phytimer_clk_src.c),
@@ -958,6 +984,7 @@ static struct rcg_clk csi2phytimer_clk_src = {
.c = {
.dbg_name = "csi2phytimer_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 100000000, LOW, 200000000,
NOMINAL, 269333333),
CLK_INIT(csi2phytimer_clk_src.c),
@@ -978,6 +1005,7 @@ static struct rcg_clk dp_gtc_clk_src = {
.c = {
.dbg_name = "dp_gtc_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP2(LOWER, 40000000, LOW, 300000000),
CLK_INIT(dp_gtc_clk_src.c),
},
@@ -997,6 +1025,7 @@ static struct rcg_clk esc0_clk_src = {
.c = {
.dbg_name = "esc0_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP2(LOWER, 19200000, NOMINAL, 19200000),
CLK_INIT(esc0_clk_src.c),
},
@@ -1011,6 +1040,7 @@ static struct rcg_clk esc1_clk_src = {
.c = {
.dbg_name = "esc1_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP2(LOWER, 19200000, NOMINAL, 19200000),
CLK_INIT(esc1_clk_src.c),
},
@@ -1033,6 +1063,7 @@ static struct rcg_clk extpclk_clk_src = {
.dbg_name = "extpclk_clk_src",
.parent = &ext_extpclk_clk_src.c,
.ops = &clk_ops_byte,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 150000000, LOW, 300000000,
NOMINAL, 600000000),
CLK_INIT(extpclk_clk_src.c),
@@ -1053,6 +1084,7 @@ static struct rcg_clk hdmi_clk_src = {
.c = {
.dbg_name = "hdmi_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP2(LOWER, 19200000, NOMINAL, 19200000),
CLK_INIT(hdmi_clk_src.c),
},
@@ -1072,6 +1104,7 @@ static struct rcg_clk vsync_clk_src = {
.c = {
.dbg_name = "vsync_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP2(LOWER, 19200000, NOMINAL, 19200000),
CLK_INIT(vsync_clk_src.c),
},
@@ -1091,6 +1124,7 @@ static struct rcg_clk dp_aux_clk_src = {
.c = {
.dbg_name = "dp_aux_clk_src",
.ops = &clk_ops_rcg,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP2(LOWER, 19200000, NOMINAL, 19200000),
CLK_INIT(dp_aux_clk_src.c),
},
@@ -1165,6 +1199,7 @@ static struct rcg_clk dp_crypto_clk_src = {
.c = {
.dbg_name = "dp_crypto_clk_src",
.ops = &clk_ops_rcg_mnd,
+ .flags = CLKFLAG_NO_RATE_CACHE,
VDD_DIG_FMAX_MAP3(LOWER, 101250, LOW, 168750,
NOMINAL, 337500),
CLK_INIT(dp_crypto_clk_src.c),
@@ -1237,6 +1272,7 @@ static struct branch_clk mmss_camss_cci_clk = {
.c = {
.dbg_name = "mmss_camss_cci_clk",
.parent = &cci_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_cci_clk.c),
},
@@ -1260,6 +1296,7 @@ static struct branch_clk mmss_camss_cpp_clk = {
.c = {
.dbg_name = "mmss_camss_cpp_clk",
.parent = &cpp_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_cpp_clk.c),
},
@@ -1317,6 +1354,7 @@ static struct branch_clk mmss_camss_csi0_clk = {
.c = {
.dbg_name = "mmss_camss_csi0_clk",
.parent = &csi0_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_csi0_clk.c),
},
@@ -1376,6 +1414,7 @@ static struct branch_clk mmss_camss_csi1_clk = {
.c = {
.dbg_name = "mmss_camss_csi1_clk",
.parent = &csi1_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_csi1_clk.c),
},
@@ -1435,6 +1474,7 @@ static struct branch_clk mmss_camss_csi2_clk = {
.c = {
.dbg_name = "mmss_camss_csi2_clk",
.parent = &csi2_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_csi2_clk.c),
},
@@ -1494,6 +1534,7 @@ static struct branch_clk mmss_camss_csi3_clk = {
.c = {
.dbg_name = "mmss_camss_csi3_clk",
.parent = &csi3_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_csi3_clk.c),
},
@@ -1555,6 +1596,7 @@ static struct branch_clk mmss_camss_csiphy0_clk = {
.c = {
.dbg_name = "mmss_camss_csiphy0_clk",
.parent = &csiphy_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_csiphy0_clk.c),
},
@@ -1568,6 +1610,7 @@ static struct branch_clk mmss_camss_csiphy1_clk = {
.c = {
.dbg_name = "mmss_camss_csiphy1_clk",
.parent = &csiphy_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_csiphy1_clk.c),
},
@@ -1581,6 +1624,7 @@ static struct branch_clk mmss_camss_csiphy2_clk = {
.c = {
.dbg_name = "mmss_camss_csiphy2_clk",
.parent = &csiphy_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_csiphy2_clk.c),
},
@@ -1604,6 +1648,7 @@ static struct branch_clk mmss_fd_core_clk = {
.c = {
.dbg_name = "mmss_fd_core_clk",
.parent = &fd_core_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_fd_core_clk.c),
},
@@ -1628,6 +1673,7 @@ static struct branch_clk mmss_camss_gp0_clk = {
.c = {
.dbg_name = "mmss_camss_gp0_clk",
.parent = &camss_gp0_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_gp0_clk.c),
},
@@ -1640,6 +1686,7 @@ static struct branch_clk mmss_camss_gp1_clk = {
.c = {
.dbg_name = "mmss_camss_gp1_clk",
.parent = &camss_gp1_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_gp1_clk.c),
},
@@ -1663,6 +1710,7 @@ static struct branch_clk mmss_camss_jpeg0_clk = {
.c = {
.dbg_name = "mmss_camss_jpeg0_clk",
.parent = &jpeg0_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_jpeg0_clk.c),
},
@@ -1701,6 +1749,7 @@ static struct branch_clk mmss_camss_mclk0_clk = {
.c = {
.dbg_name = "mmss_camss_mclk0_clk",
.parent = &mclk0_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_mclk0_clk.c),
},
@@ -1713,6 +1762,7 @@ static struct branch_clk mmss_camss_mclk1_clk = {
.c = {
.dbg_name = "mmss_camss_mclk1_clk",
.parent = &mclk1_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_mclk1_clk.c),
},
@@ -1725,6 +1775,7 @@ static struct branch_clk mmss_camss_mclk2_clk = {
.c = {
.dbg_name = "mmss_camss_mclk2_clk",
.parent = &mclk2_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_mclk2_clk.c),
},
@@ -1737,6 +1788,7 @@ static struct branch_clk mmss_camss_mclk3_clk = {
.c = {
.dbg_name = "mmss_camss_mclk3_clk",
.parent = &mclk3_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_mclk3_clk.c),
},
@@ -1760,6 +1812,7 @@ static struct branch_clk mmss_camss_csi0phytimer_clk = {
.c = {
.dbg_name = "mmss_camss_csi0phytimer_clk",
.parent = &csi0phytimer_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_csi0phytimer_clk.c),
},
@@ -1772,6 +1825,7 @@ static struct branch_clk mmss_camss_csi1phytimer_clk = {
.c = {
.dbg_name = "mmss_camss_csi1phytimer_clk",
.parent = &csi1phytimer_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_csi1phytimer_clk.c),
},
@@ -1784,6 +1838,7 @@ static struct branch_clk mmss_camss_csi2phytimer_clk = {
.c = {
.dbg_name = "mmss_camss_csi2phytimer_clk",
.parent = &csi2phytimer_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_csi2phytimer_clk.c),
},
@@ -1818,6 +1873,7 @@ static struct branch_clk mmss_camss_vfe0_clk = {
.c = {
.dbg_name = "mmss_camss_vfe0_clk",
.parent = &vfe0_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_vfe0_clk.c),
},
@@ -1853,6 +1909,7 @@ static struct branch_clk mmss_camss_vfe1_clk = {
.c = {
.dbg_name = "mmss_camss_vfe1_clk",
.parent = &vfe1_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_camss_vfe1_clk.c),
},
@@ -1921,6 +1978,7 @@ static struct branch_clk mmss_mdss_byte0_clk = {
.c = {
.dbg_name = "mmss_mdss_byte0_clk",
.parent = &byte0_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_byte0_clk.c),
},
@@ -1956,6 +2014,7 @@ static struct branch_clk mmss_mdss_byte0_intf_clk = {
.c = {
.dbg_name = "mmss_mdss_byte0_intf_clk",
.parent = &mmss_mdss_byte0_intf_div_clk.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_byte0_intf_clk.c),
},
@@ -1968,6 +2027,7 @@ static struct branch_clk mmss_mdss_byte1_clk = {
.c = {
.dbg_name = "mmss_mdss_byte1_clk",
.parent = &byte1_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_byte1_clk.c),
},
@@ -2003,6 +2063,7 @@ static struct branch_clk mmss_mdss_byte1_intf_clk = {
.c = {
.dbg_name = "mmss_mdss_byte1_intf_clk",
.parent = &mmss_mdss_byte1_intf_div_clk.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_byte1_intf_clk.c),
},
@@ -2015,6 +2076,7 @@ static struct branch_clk mmss_mdss_dp_aux_clk = {
.c = {
.dbg_name = "mmss_mdss_dp_aux_clk",
.parent = &dp_aux_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_dp_aux_clk.c),
},
@@ -2066,6 +2128,7 @@ static struct branch_clk mmss_mdss_dp_crypto_clk = {
.c = {
.dbg_name = "mmss_mdss_dp_crypto_clk",
.parent = &dp_crypto_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_dp_crypto_clk.c),
},
@@ -2078,6 +2141,7 @@ static struct branch_clk mmss_mdss_dp_gtc_clk = {
.c = {
.dbg_name = "mmss_mdss_dp_gtc_clk",
.parent = &dp_gtc_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_dp_gtc_clk.c),
},
@@ -2090,6 +2154,7 @@ static struct branch_clk mmss_mdss_esc0_clk = {
.c = {
.dbg_name = "mmss_mdss_esc0_clk",
.parent = &esc0_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_esc0_clk.c),
},
@@ -2102,6 +2167,7 @@ static struct branch_clk mmss_mdss_esc1_clk = {
.c = {
.dbg_name = "mmss_mdss_esc1_clk",
.parent = &esc1_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_esc1_clk.c),
},
@@ -2114,6 +2180,7 @@ static struct branch_clk mmss_mdss_extpclk_clk = {
.c = {
.dbg_name = "mmss_mdss_extpclk_clk",
.parent = &extpclk_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_extpclk_clk.c),
},
@@ -2126,6 +2193,7 @@ static struct branch_clk mmss_mdss_hdmi_clk = {
.c = {
.dbg_name = "mmss_mdss_hdmi_clk",
.parent = &hdmi_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_hdmi_clk.c),
},
@@ -2149,6 +2217,7 @@ static struct branch_clk mmss_mdss_mdp_clk = {
.c = {
.dbg_name = "mmss_mdss_mdp_clk",
.parent = &mdp_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_mdp_clk.c),
},
@@ -2175,6 +2244,7 @@ static struct branch_clk mmss_mdss_pclk0_clk = {
.c = {
.dbg_name = "mmss_mdss_pclk0_clk",
.parent = &pclk0_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_pclk0_clk.c),
},
@@ -2187,6 +2257,7 @@ static struct branch_clk mmss_mdss_pclk1_clk = {
.c = {
.dbg_name = "mmss_mdss_pclk1_clk",
.parent = &pclk1_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_pclk1_clk.c),
},
@@ -2199,6 +2270,7 @@ static struct branch_clk mmss_mdss_rot_clk = {
.c = {
.dbg_name = "mmss_mdss_rot_clk",
.parent = &rot_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_rot_clk.c),
},
@@ -2211,6 +2283,7 @@ static struct branch_clk mmss_mdss_vsync_clk = {
.c = {
.dbg_name = "mmss_mdss_vsync_clk",
.parent = &vsync_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_vsync_clk.c),
},
@@ -2225,6 +2298,7 @@ static struct branch_clk mmss_mnoc_ahb_clk = {
.c = {
.dbg_name = "mmss_mnoc_ahb_clk",
.parent = &ahb_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mnoc_ahb_clk.c),
},
@@ -2260,6 +2334,7 @@ static struct branch_clk mmss_mnoc_maxi_clk = {
.c = {
.dbg_name = "mmss_mnoc_maxi_clk",
.parent = &maxi_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mnoc_maxi_clk.c),
},
@@ -2272,6 +2347,7 @@ static struct branch_clk mmss_video_subcore0_clk = {
.c = {
.dbg_name = "mmss_video_subcore0_clk",
.parent = &video_subcore0_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_video_subcore0_clk.c),
},
@@ -2284,6 +2360,7 @@ static struct branch_clk mmss_video_subcore1_clk = {
.c = {
.dbg_name = "mmss_video_subcore1_clk",
.parent = &video_subcore1_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_video_subcore1_clk.c),
},
@@ -2318,6 +2395,7 @@ static struct branch_clk mmss_video_core_clk = {
.c = {
.dbg_name = "mmss_video_core_clk",
.parent = &video_core_clk_src.c,
+ .flags = CLKFLAG_NO_RATE_CACHE,
.ops = &clk_ops_branch,
CLK_INIT(mmss_video_core_clk.c),
},
@@ -2822,6 +2900,9 @@ int msm_mmsscc_cobalt_probe(struct platform_device *pdev)
ext_dp_phy_pll_vco.clk_id = "dp_vco_div";
ext_dp_phy_pll_vco.c.flags = CLKFLAG_NO_RATE_CACHE;
+ mmss_camss_jpeg0_vote_clk.c.flags = CLKFLAG_NO_RATE_CACHE;
+ mmss_camss_jpeg0_dma_vote_clk.c.flags = CLKFLAG_NO_RATE_CACHE;
+
is_vq = of_device_is_compatible(pdev->dev.of_node,
"qcom,mmsscc-hamster");
if (is_vq)
diff --git a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c b/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c
index a574a9cd2b5a..93bbcf5d40f5 100644
--- a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c
+++ b/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c
@@ -275,7 +275,7 @@ int dp_config_vco_rate(struct dp_pll_vco_clk *vco, unsigned long rate)
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00);
MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_DIV_FRAC_START3_MODE0, 0xa0);
+ QSERDES_COM_DIV_FRAC_START3_MODE0, 0x0a);
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_CMN_CONFIG, 0x12);
MDSS_PLL_REG_W(dp_res->pll_base,
@@ -733,7 +733,7 @@ unsigned long dp_vco_get_rate(struct clk *c)
{
struct dp_pll_vco_clk *vco = mdss_dp_to_vco_clk(c);
int rc;
- u32 div, hsclk_div, link2xclk_div;
+ u32 div, hsclk_div, link2xclk_div = 0;
u64 vco_rate;
struct mdss_pll_resources *pll = vco->priv;
diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c b/drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c
index 4b2d8bba0940..299934c86d05 100644
--- a/drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c
+++ b/drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c
@@ -205,18 +205,34 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_cobalt *pll,
struct dsi_pll_regs *regs = &pll->reg_setup;
u64 target_freq;
u64 fref = rsc->vco_ref_clk_rate;
- u32 computed_output_div, div_log;
+ u32 computed_output_div, div_log = 0;
u64 pll_freq;
u64 divider;
u64 dec, dec_multiple;
u32 frac;
u64 multiplier;
+ u32 i;
target_freq = rsc->vco_current_rate;
pr_debug("target_freq = %llu\n", target_freq);
if (config->div_override) {
computed_output_div = config->output_div;
+
+ /*
+ * Computed_output_div = 2 ^ div_log
+ * To get div_log from output div just get the index of the
+ * 1 bit in the value.
+ * div_log ranges from 0-3. so check the 4 lsbs
+ */
+
+ for (i = 0; i < 4; i++) {
+ if (computed_output_div & (1 << i)) {
+ div_log = i;
+ break;
+ }
+ }
+
} else {
if (target_freq < MHZ_375) {
computed_output_div = 8;
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 4d46d65898d1..f685e7fe3a4d 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2016, 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
@@ -20,28 +20,34 @@
#include "clk-alpha-pll.h"
#define PLL_MODE 0x00
-# define PLL_OUTCTRL BIT(0)
-# define PLL_BYPASSNL BIT(1)
-# define PLL_RESET_N BIT(2)
-# define PLL_LOCK_COUNT_SHIFT 8
-# define PLL_LOCK_COUNT_MASK 0x3f
-# define PLL_BIAS_COUNT_SHIFT 14
-# define PLL_BIAS_COUNT_MASK 0x3f
-# define PLL_VOTE_FSM_ENA BIT(20)
-# define PLL_VOTE_FSM_RESET BIT(21)
-# define PLL_ACTIVE_FLAG BIT(30)
-# define PLL_LOCK_DET BIT(31)
+#define PLL_OUTCTRL BIT(0)
+#define PLL_BYPASSNL BIT(1)
+#define PLL_RESET_N BIT(2)
+#define PLL_LOCK_COUNT_SHIFT 8
+#define PLL_LOCK_COUNT_MASK 0x3f
+#define PLL_LOCK_COUNT_VAL 0x0
+#define PLL_BIAS_COUNT_SHIFT 14
+#define PLL_BIAS_COUNT_MASK 0x3f
+#define PLL_BIAS_COUNT_VAL 0x6
+#define PLL_LATCH_INTERFACE BIT(11)
+#define PLL_VOTE_FSM_ENA BIT(20)
+#define PLL_VOTE_FSM_RESET BIT(21)
+#define PLL_UPDATE BIT(22)
+#define PLL_HW_UPDATE_LOGIC_BYPASS BIT(23)
+#define PLL_ALPHA_EN BIT(24)
+#define PLL_ACTIVE_FLAG BIT(30)
+#define PLL_LOCK_DET BIT(31)
+#define PLL_ACK_LATCH BIT(29)
#define PLL_L_VAL 0x04
#define PLL_ALPHA_VAL 0x08
#define PLL_ALPHA_VAL_U 0x0c
#define PLL_USER_CTL 0x10
-# define PLL_POST_DIV_SHIFT 8
-# define PLL_POST_DIV_MASK 0xf
-# define PLL_ALPHA_EN BIT(24)
-# define PLL_VCO_SHIFT 20
-# define PLL_VCO_MASK 0x3
+#define PLL_POST_DIV_SHIFT 8
+#define PLL_POST_DIV_MASK 0xf
+#define PLL_VCO_SHIFT 20
+#define PLL_VCO_MASK 0x3
#define PLL_USER_CTL_U 0x14
@@ -79,7 +85,7 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
if (ret)
return ret;
- if (inverse && (val & mask))
+ if (inverse && !(val & mask))
return 0;
else if ((val & mask) == mask)
return 0;
@@ -106,6 +112,15 @@ static int wait_for_pll_offline(struct clk_alpha_pll *pll, u32 mask)
return wait_for_pll(pll, mask, 0, "offline");
}
+static int wait_for_pll_latch_ack(struct clk_alpha_pll *pll, u32 mask)
+{
+ return wait_for_pll(pll, mask, 0, "latch_ack");
+}
+
+static int wait_for_pll_update(struct clk_alpha_pll *pll, u32 mask)
+{
+ return wait_for_pll(pll, mask, 1, "update");
+}
/* alpha pll with hwfsm support */
@@ -114,29 +129,103 @@ static int wait_for_pll_offline(struct clk_alpha_pll *pll, u32 mask)
#define PLL_OFFLINE_ACK BIT(28)
#define PLL_ACTIVE_FLAG BIT(30)
+static void clk_alpha_set_fsm_mode(struct clk_alpha_pll *pll)
+{
+ u32 val;
+
+ regmap_read(pll->clkr.regmap, pll->offset + PLL_MODE, &val);
+
+ /* De-assert reset to FSM */
+ val &= ~PLL_VOTE_FSM_RESET;
+
+ /* Program bias count */
+ val &= ~(PLL_BIAS_COUNT_MASK << PLL_BIAS_COUNT_SHIFT);
+ val |= PLL_BIAS_COUNT_VAL << PLL_BIAS_COUNT_SHIFT;
+
+ /* Program lock count */
+ val &= ~(PLL_LOCK_COUNT_MASK << PLL_LOCK_COUNT_SHIFT);
+ val |= PLL_LOCK_COUNT_VAL << PLL_LOCK_COUNT_SHIFT;
+
+ /* Enable PLL FSM voting */
+ val |= PLL_VOTE_FSM_ENA;
+
+ regmap_write(pll->clkr.regmap, pll->offset + PLL_MODE, val);
+}
+
void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
- const struct pll_config *config)
+ const struct pll_config *config)
{
u32 val, mask;
- regmap_write(regmap, pll->offset + PLL_CONFIG_CTL,
- config->config_ctl_val);
+ if (config->l)
+ regmap_write(regmap, pll->offset + PLL_L_VAL,
+ config->l);
+ if (config->alpha)
+ regmap_write(regmap, pll->offset + PLL_ALPHA_VAL,
+ config->alpha);
+ if (config->alpha_u)
+ regmap_write(regmap, pll->offset + PLL_ALPHA_VAL_U,
+ config->alpha_u);
+ if (config->config_ctl_val)
+ regmap_write(regmap, pll->offset + PLL_CONFIG_CTL,
+ config->config_ctl_val);
+
+ if (config->main_output_mask || config->aux_output_mask ||
+ config->aux2_output_mask || config->early_output_mask ||
+ config->vco_val || config->alpha_en_mask) {
+
+ val = config->main_output_mask;
+ val |= config->aux_output_mask;
+ val |= config->aux2_output_mask;
+ val |= config->early_output_mask;
+ val |= config->vco_val;
+ val |= config->alpha_en_mask;
+
+ mask = config->main_output_mask;
+ mask |= config->aux_output_mask;
+ mask |= config->aux2_output_mask;
+ mask |= config->early_output_mask;
+ mask |= config->vco_mask;
+ mask |= config->alpha_en_mask;
+
+ regmap_update_bits(regmap, pll->offset + PLL_USER_CTL,
+ mask, val);
+ }
+
+ if (config->post_div_mask) {
+ mask = config->post_div_mask;
+ val = config->post_div_val;
+ regmap_update_bits(regmap, pll->offset + PLL_USER_CTL,
+ mask, val);
+ }
- val = config->main_output_mask;
- val |= config->aux_output_mask;
- val |= config->aux2_output_mask;
- val |= config->early_output_mask;
- val |= config->post_div_val;
+ /* Do not bypass the latch interface */
+ if (pll->flags & SUPPORTS_SLEW)
+ regmap_update_bits(regmap, pll->offset + PLL_USER_CTL_U,
+ PLL_LATCH_INTERFACE, (u32)~PLL_LATCH_INTERFACE);
+
+ if (pll->flags & SUPPORTS_DYNAMIC_UPDATE) {
+ regmap_update_bits(regmap, pll->offset + PLL_MODE,
+ PLL_HW_UPDATE_LOGIC_BYPASS,
+ PLL_HW_UPDATE_LOGIC_BYPASS);
+ }
- mask = config->main_output_mask;
- mask |= config->aux_output_mask;
- mask |= config->aux2_output_mask;
- mask |= config->early_output_mask;
- mask |= config->post_div_mask;
+ if (config->test_ctl_lo_mask) {
+ mask = config->test_ctl_lo_mask;
+ val = config->test_ctl_lo_val;
+ regmap_update_bits(regmap, pll->offset + PLL_TEST_CTL,
+ mask, val);
+ }
- regmap_update_bits(regmap, pll->offset + PLL_USER_CTL, mask, val);
+ if (config->test_ctl_hi_mask) {
+ mask = config->test_ctl_hi_mask;
+ val = config->test_ctl_hi_val;
+ regmap_update_bits(regmap, pll->offset + PLL_TEST_CTL_U,
+ mask, val);
+ }
- return;
+ if (pll->flags & SUPPORTS_FSM_MODE)
+ clk_alpha_set_fsm_mode(pll);
}
static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
@@ -190,8 +279,9 @@ static void clk_alpha_pll_hwfsm_disable(struct clk_hw *hw)
PLL_FSM_ENA, 0);
if (ret)
return;
+
wait_for_pll_disable(pll, PLL_ACTIVE_FLAG);
- return;
+
}
static int clk_alpha_pll_enable(struct clk_hw *hw)
@@ -201,7 +291,6 @@ static int clk_alpha_pll_enable(struct clk_hw *hw)
u32 val, mask, off;
off = pll->offset;
-
mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL;
ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
if (ret)
@@ -339,7 +428,53 @@ clk_alpha_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
a >>= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH;
}
- return alpha_pll_calc_rate(prate, l, a);
+ ctl >>= PLL_POST_DIV_SHIFT;
+ ctl &= PLL_POST_DIV_MASK;
+
+ return alpha_pll_calc_rate(prate, l, a) >> fls(ctl);
+}
+
+static int clk_alpha_pll_dynamic_update(struct clk_alpha_pll *pll)
+{
+ int ret;
+
+ /* Latch the input to the PLL */
+ regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_MODE,
+ PLL_UPDATE, PLL_UPDATE);
+
+ /* Wait for 2 reference cycle before checking ACK bit */
+ udelay(1);
+
+ ret = wait_for_pll_latch_ack(pll, PLL_ACK_LATCH);
+ if (ret)
+ return ret;
+
+ /* Return latch input to 0 */
+ regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_MODE,
+ PLL_UPDATE, (u32)~PLL_UPDATE);
+
+ ret = wait_for_pll_enable(pll, PLL_LOCK_DET);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static const struct pll_vco_data
+ *find_vco_data(const struct pll_vco_data *data,
+ unsigned long rate, size_t size)
+{
+ int i;
+
+ if (!data)
+ return NULL;
+
+ for (i = 0; i < size; i++) {
+ if (rate == data[i].freq)
+ return &data[i];
+ }
+
+ return &data[i - 1];
}
static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -347,16 +482,36 @@ static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
{
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
const struct pll_vco *vco;
+ const struct pll_vco_data *data;
+ bool is_enabled;
u32 l, off = pll->offset;
u64 a;
+ unsigned long rrate;
+
+ rrate = alpha_pll_round_rate(rate, prate, &l, &a);
+
+ if (rrate != rate) {
+ pr_err("alpha_pll: Call clk_set_rate with rounded rates!\n");
+ return -EINVAL;
+ }
- rate = alpha_pll_round_rate(rate, prate, &l, &a);
- vco = alpha_pll_find_vco(pll, rate);
+ vco = alpha_pll_find_vco(pll, rrate);
if (!vco) {
pr_err("alpha pll not in a valid vco range\n");
return -EINVAL;
}
+ is_enabled = clk_hw_is_enabled(hw);
+
+ /*
+ * For PLLs that do not support dynamic programming (dynamic_update
+ * is not set), ensure PLL is off before changing rate. For
+ * optimization reasons, assume no downstream clock is actively
+ * using it.
+ */
+ if (is_enabled && !(pll->flags & SUPPORTS_DYNAMIC_UPDATE))
+ hw->init->ops->disable(hw);
+
a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);
regmap_write(pll->clkr.regmap, off + PLL_L_VAL, l);
@@ -367,9 +522,27 @@ static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
PLL_VCO_MASK << PLL_VCO_SHIFT,
vco->val << PLL_VCO_SHIFT);
+ data = find_vco_data(pll->vco_data, rate, pll->num_vco_data);
+ if (data) {
+ if (data->freq == rate)
+ regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL,
+ PLL_POST_DIV_MASK << PLL_POST_DIV_SHIFT,
+ data->post_div_val << PLL_POST_DIV_SHIFT);
+ else
+ regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL,
+ PLL_POST_DIV_MASK << PLL_POST_DIV_SHIFT,
+ 0x0 << PLL_VCO_SHIFT);
+ }
+
regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL, PLL_ALPHA_EN,
PLL_ALPHA_EN);
+ if (is_enabled && (pll->flags & SUPPORTS_DYNAMIC_UPDATE))
+ clk_alpha_pll_dynamic_update(pll);
+
+ if (is_enabled && !(pll->flags & SUPPORTS_DYNAMIC_UPDATE))
+ hw->init->ops->enable(hw);
+
return 0;
}
@@ -381,6 +554,9 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
u64 a;
unsigned long min_freq, max_freq;
+ if (rate < pll->min_supported_freq)
+ return pll->min_supported_freq;
+
rate = alpha_pll_round_rate(rate, *prate, &l, &a);
if (alpha_pll_find_vco(pll, rate))
return rate;
@@ -391,12 +567,48 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
return clamp(rate, min_freq, max_freq);
}
+static void clk_alpha_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
+{
+ struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+ int size, i, val;
+
+ static struct clk_register_data data[] = {
+ {"PLL_MODE", 0x0},
+ {"PLL_L_VAL", 0x4},
+ {"PLL_ALPHA_VAL", 0x8},
+ {"PLL_ALPHA_VAL_U", 0xC},
+ {"PLL_USER_CTL", 0x10},
+ {"PLL_CONFIG_CTL", 0x18},
+ };
+
+ static struct clk_register_data data1[] = {
+ {"APSS_PLL_VOTE", 0x0},
+ };
+
+ size = ARRAY_SIZE(data);
+
+ for (i = 0; i < size; i++) {
+ regmap_read(pll->clkr.regmap, pll->offset + data[i].offset,
+ &val);
+ seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
+ }
+
+ regmap_read(pll->clkr.regmap, pll->offset + data[0].offset, &val);
+
+ if (val & PLL_FSM_ENA) {
+ regmap_read(pll->clkr.regmap, pll->clkr.enable_reg +
+ data1[0].offset, &val);
+ seq_printf(f, "%20s: 0x%.8x\n", data1[0].name, val);
+ }
+}
+
const struct clk_ops clk_alpha_pll_ops = {
.enable = clk_alpha_pll_enable,
.disable = clk_alpha_pll_disable,
.recalc_rate = clk_alpha_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
.set_rate = clk_alpha_pll_set_rate,
+ .list_registers = clk_alpha_pll_list_registers,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_ops);
@@ -406,6 +618,7 @@ const struct clk_ops clk_alpha_pll_hwfsm_ops = {
.recalc_rate = clk_alpha_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
.set_rate = clk_alpha_pll_set_rate,
+ .list_registers = clk_alpha_pll_list_registers,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops);
@@ -462,3 +675,177 @@ const struct clk_ops clk_alpha_pll_postdiv_ops = {
.set_rate = clk_alpha_pll_postdiv_set_rate,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_ops);
+
+static int clk_alpha_pll_slew_update(struct clk_alpha_pll *pll)
+{
+ int ret = 0;
+ u32 val;
+
+ regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_MODE,
+ PLL_UPDATE, PLL_UPDATE);
+ regmap_read(pll->clkr.regmap, pll->offset + PLL_MODE, &val);
+
+ ret = wait_for_pll_update(pll, PLL_UPDATE);
+ if (ret)
+ return ret;
+ /*
+ * HPG mandates a wait of at least 570ns before polling the LOCK
+ * detect bit. Have a delay of 1us just to be safe.
+ */
+ mb();
+ udelay(1);
+
+ ret = wait_for_pll_enable(pll, PLL_LOCK_DET);
+
+ return ret;
+}
+
+static int clk_alpha_pll_slew_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+ unsigned long freq_hz;
+ const struct pll_vco *curr_vco, *vco;
+ u32 l;
+ u64 a;
+
+ freq_hz = alpha_pll_round_rate(rate, parent_rate, &l, &a);
+ if (freq_hz != rate) {
+ pr_err("alpha_pll: Call clk_set_rate with rounded rates!\n");
+ return -EINVAL;
+ }
+
+ curr_vco = alpha_pll_find_vco(pll, clk_hw_get_rate(hw));
+ if (!curr_vco) {
+ pr_err("alpha pll: not in a valid vco range\n");
+ return -EINVAL;
+ }
+
+ vco = alpha_pll_find_vco(pll, freq_hz);
+ if (!vco) {
+ pr_err("alpha pll: not in a valid vco range\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Dynamic pll update will not support switching frequencies across
+ * vco ranges. In those cases fall back to normal alpha set rate.
+ */
+ if (curr_vco->val != vco->val)
+ return clk_alpha_pll_set_rate(hw, rate, parent_rate);
+
+ a = a << (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);
+
+ regmap_write(pll->clkr.regmap, pll->offset + PLL_L_VAL, l);
+ regmap_write(pll->clkr.regmap, pll->offset + PLL_ALPHA_VAL, a);
+ regmap_write(pll->clkr.regmap, pll->offset + PLL_ALPHA_VAL_U, a >> 32);
+
+ /* Ensure that the write above goes through before proceeding. */
+ mb();
+
+ if (clk_hw_is_enabled(hw))
+ clk_alpha_pll_slew_update(pll);
+
+ return 0;
+}
+
+/*
+ * Slewing plls should be bought up at frequency which is in the middle of the
+ * desired VCO range. So after bringing up the pll at calibration freq, set it
+ * back to desired frequency(that was set by previous clk_set_rate).
+ */
+static int clk_alpha_pll_calibrate(struct clk_hw *hw)
+{
+ unsigned long calibration_freq, freq_hz;
+ struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+ const struct pll_vco *vco;
+ u64 a;
+ u32 l;
+ int rc;
+
+ vco = alpha_pll_find_vco(pll, clk_hw_get_rate(hw));
+ if (!vco) {
+ pr_err("alpha pll: not in a valid vco range\n");
+ return -EINVAL;
+ }
+
+ /*
+ * As during slewing plls vco_sel won't be allowed to change, vco table
+ * should have only one entry table, i.e. index = 0, find the
+ * calibration frequency.
+ */
+ calibration_freq = (pll->vco_table[0].min_freq +
+ pll->vco_table[0].max_freq)/2;
+
+ freq_hz = alpha_pll_round_rate(calibration_freq,
+ clk_hw_get_rate(clk_hw_get_parent(hw)), &l, &a);
+ if (freq_hz != calibration_freq) {
+ pr_err("alpha_pll: call clk_set_rate with rounded rates!\n");
+ return -EINVAL;
+ }
+
+ /* Setup PLL for calibration frequency */
+ a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);
+
+ regmap_write(pll->clkr.regmap, pll->offset + PLL_L_VAL, l);
+ regmap_write(pll->clkr.regmap, pll->offset + PLL_ALPHA_VAL, a);
+ regmap_write(pll->clkr.regmap, pll->offset + PLL_ALPHA_VAL_U, a >> 32);
+
+ regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_USER_CTL,
+ PLL_VCO_MASK << PLL_VCO_SHIFT,
+ vco->val << PLL_VCO_SHIFT);
+
+ regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_USER_CTL,
+ PLL_ALPHA_EN, PLL_ALPHA_EN);
+
+ /* Bringup the pll at calibration frequency */
+ rc = clk_alpha_pll_enable(hw);
+ if (rc) {
+ pr_err("alpha pll calibration failed\n");
+ return rc;
+ }
+
+ /*
+ * PLL is already running at calibration frequency.
+ * So slew pll to the previously set frequency.
+ */
+ freq_hz = alpha_pll_round_rate(clk_hw_get_rate(hw),
+ clk_hw_get_rate(clk_hw_get_parent(hw)), &l, &a);
+
+ pr_debug("pll %s: setting back to required rate %lu, freq_hz %ld\n",
+ hw->init->name, clk_hw_get_rate(hw), freq_hz);
+
+ /* Setup the PLL for the new frequency */
+ a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);
+
+ regmap_write(pll->clkr.regmap, pll->offset + PLL_L_VAL, l);
+ regmap_write(pll->clkr.regmap, pll->offset + PLL_ALPHA_VAL, a);
+ regmap_write(pll->clkr.regmap, pll->offset + PLL_ALPHA_VAL_U, a >> 32);
+
+ regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_USER_CTL,
+ PLL_ALPHA_EN, PLL_ALPHA_EN);
+
+ return clk_alpha_pll_slew_update(pll);
+}
+
+static int clk_alpha_pll_slew_enable(struct clk_hw *hw)
+{
+ int rc;
+
+ rc = clk_alpha_pll_calibrate(hw);
+ if (rc)
+ return rc;
+
+ rc = clk_alpha_pll_enable(hw);
+
+ return rc;
+}
+
+const struct clk_ops clk_alpha_pll_slew_ops = {
+ .enable = clk_alpha_pll_slew_enable,
+ .disable = clk_alpha_pll_disable,
+ .recalc_rate = clk_alpha_pll_recalc_rate,
+ .round_rate = clk_alpha_pll_round_rate,
+ .set_rate = clk_alpha_pll_slew_set_rate,
+};
+EXPORT_SYMBOL_GPL(clk_alpha_pll_slew_ops);
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index 7718bd5beefc..dd92bc340f8a 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2016, 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
@@ -18,6 +18,11 @@
#include "clk-regmap.h"
#include "clk-pll.h"
+struct pll_vco_data {
+ unsigned long freq;
+ u8 post_div_val;
+};
+
struct pll_vco {
unsigned long min_freq;
unsigned long max_freq;
@@ -28,21 +33,35 @@ struct pll_vco {
* struct clk_alpha_pll - phase locked loop (PLL)
* @offset: base address of registers
* @vco_table: array of VCO settings
+ * @vco_data: array of VCO data settings like post div
* @clkr: regmap clock handle
*/
struct clk_alpha_pll {
u32 offset;
+ struct pll_config *config;
const struct pll_vco *vco_table;
size_t num_vco;
+ const struct pll_vco_data *vco_data;
+ size_t num_vco_data;
+
+ u8 flags;
+#define SUPPORTS_FSM_MODE BIT(0)
+ /* some PLLs support dynamically updating their rate
+ * without disabling the PLL first. Set this flag
+ * to enable this support.
+ */
+#define SUPPORTS_DYNAMIC_UPDATE BIT(1)
+#define SUPPORTS_SLEW BIT(2)
+
struct clk_regmap clkr;
- u32 config_ctl_val;
#define PLLOUT_MAIN BIT(0)
#define PLLOUT_AUX BIT(1)
#define PLLOUT_AUX2 BIT(2)
#define PLLOUT_EARLY BIT(3)
u32 pllout_flags;
+ unsigned long min_supported_freq;
};
/**
@@ -61,6 +80,7 @@ struct clk_alpha_pll_postdiv {
extern const struct clk_ops clk_alpha_pll_ops;
extern const struct clk_ops clk_alpha_pll_hwfsm_ops;
extern const struct clk_ops clk_alpha_pll_postdiv_ops;
+extern const struct clk_ops clk_alpha_pll_slew_ops;
void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct pll_config *config);
diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c
index 8aea1d519311..6a975052cc85 100644
--- a/drivers/clk/qcom/clk-branch.c
+++ b/drivers/clk/qcom/clk-branch.c
@@ -16,10 +16,12 @@
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/export.h>
+#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/regmap.h>
#include "clk-branch.h"
+#include "clk-regmap.h"
static bool clk_branch_in_hwcg_mode(const struct clk_branch *br)
{
@@ -181,6 +183,43 @@ const struct clk_ops clk_branch_ops = {
};
EXPORT_SYMBOL_GPL(clk_branch_ops);
+static void clk_branch2_list_registers(struct seq_file *f, struct clk_hw *hw)
+{
+ struct clk_branch *br = to_clk_branch(hw);
+ struct clk_regmap *rclk = to_clk_regmap(hw);
+ int size, i, val;
+
+ static struct clk_register_data data[] = {
+ {"CBCR", 0x0},
+ };
+
+ static struct clk_register_data data1[] = {
+ {"APSS_VOTE", 0x0},
+ {"APSS_SLEEP_VOTE", 0x4},
+ };
+
+ size = ARRAY_SIZE(data);
+
+ for (i = 0; i < size; i++) {
+ regmap_read(br->clkr.regmap, br->halt_reg + data[i].offset,
+ &val);
+ seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
+ }
+
+ if ((br->halt_check & BRANCH_HALT_VOTED) &&
+ !(br->halt_check & BRANCH_VOTED)) {
+ if (rclk->enable_reg) {
+ size = ARRAY_SIZE(data1);
+ for (i = 0; i < size; i++) {
+ regmap_read(br->clkr.regmap, rclk->enable_reg +
+ data1[i].offset, &val);
+ seq_printf(f, "%20s: 0x%.8x\n",
+ data1[i].name, val);
+ }
+ }
+ }
+}
+
static int clk_branch2_enable(struct clk_hw *hw)
{
return clk_branch_toggle(hw, true, clk_branch2_check_halt);
@@ -196,6 +235,7 @@ const struct clk_ops clk_branch2_ops = {
.disable = clk_branch2_disable,
.is_enabled = clk_is_enabled_regmap,
.set_flags = clk_branch_set_flags,
+ .list_registers = clk_branch2_list_registers,
};
EXPORT_SYMBOL_GPL(clk_branch2_ops);
@@ -228,10 +268,29 @@ static void clk_gate2_disable(struct clk_hw *hw)
clk_gate_toggle(hw, false);
}
+static void clk_gate2_list_registers(struct seq_file *f, struct clk_hw *hw)
+{
+ struct clk_gate2 *gt = to_clk_gate2(hw);
+ int size, i, val;
+
+ static struct clk_register_data data[] = {
+ {"EN_REG", 0x0},
+ };
+
+ size = ARRAY_SIZE(data);
+
+ for (i = 0; i < size; i++) {
+ regmap_read(gt->clkr.regmap, gt->clkr.enable_reg +
+ data[i].offset, &val);
+ seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
+ }
+}
+
const struct clk_ops clk_gate2_ops = {
.enable = clk_gate2_enable,
.disable = clk_gate2_disable,
.is_enabled = clk_is_enabled_regmap,
+ .list_registers = clk_gate2_list_registers,
};
EXPORT_SYMBOL_GPL(clk_gate2_ops);
diff --git a/drivers/clk/qcom/clk-pll.h b/drivers/clk/qcom/clk-pll.h
index 1e64fe9326d6..4f779fda785b 100644
--- a/drivers/clk/qcom/clk-pll.h
+++ b/drivers/clk/qcom/clk-pll.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016 The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -70,6 +70,8 @@ struct pll_config {
u16 l;
u32 m;
u32 n;
+ u32 alpha;
+ u32 alpha_u;
u32 vco_val;
u32 vco_mask;
u32 pre_div_val;
@@ -77,11 +79,16 @@ struct pll_config {
u32 post_div_val;
u32 post_div_mask;
u32 mn_ena_mask;
+ u32 alpha_en_mask;
u32 main_output_mask;
u32 aux_output_mask;
u32 aux2_output_mask;
u32 early_output_mask;
u32 config_ctl_val;
+ u32 test_ctl_lo_val;
+ u32 test_ctl_lo_mask;
+ u32 test_ctl_hi_val;
+ u32 test_ctl_hi_mask;
};
void clk_pll_configure_sr(struct clk_pll *pll, struct regmap *regmap,
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 6d12ddb3e245..3785a7579ce7 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -317,6 +317,53 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
return update_config(rcg);
}
+static void clk_rcg2_list_registers(struct seq_file *f, struct clk_hw *hw)
+{
+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+ int i = 0, size = 0, val;
+
+ static struct clk_register_data data[] = {
+ {"CMD_RCGR", 0x0},
+ {"CFG_RCGR", 0x4},
+ };
+
+ static struct clk_register_data data1[] = {
+ {"CMD_RCGR", 0x0},
+ {"CFG_RCGR", 0x4},
+ {"M_VAL", 0x8},
+ {"N_VAL", 0xC},
+ {"D_VAL", 0x10},
+ };
+
+ if (rcg->mnd_width) {
+ size = ARRAY_SIZE(data1);
+ for (i = 0; i < size; i++) {
+ regmap_read(rcg->clkr.regmap, (rcg->cmd_rcgr +
+ data1[i].offset), &val);
+ seq_printf(f, "%20s: 0x%.8x\n", data1[i].name, val);
+ }
+ } else {
+ size = ARRAY_SIZE(data);
+ for (i = 0; i < size; i++) {
+ regmap_read(rcg->clkr.regmap, (rcg->cmd_rcgr +
+ data[i].offset), &val);
+ seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
+ }
+ }
+}
+
+/* Return the nth supported frequency for a given clock. */
+static long clk_rcg2_list_rate(struct clk_hw *hw, unsigned n,
+ unsigned long fmax)
+{
+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+
+ if (!rcg->freq_tbl)
+ return -ENXIO;
+
+ return (rcg->freq_tbl + n)->freq;
+}
+
static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
@@ -351,6 +398,8 @@ const struct clk_ops clk_rcg2_ops = {
.determine_rate = clk_rcg2_determine_rate,
.set_rate = clk_rcg2_set_rate,
.set_rate_and_parent = clk_rcg2_set_rate_and_parent,
+ .list_rate = clk_rcg2_list_rate,
+ .list_registers = clk_rcg2_list_registers,
};
EXPORT_SYMBOL_GPL(clk_rcg2_ops);
@@ -557,6 +606,7 @@ const struct clk_ops clk_edp_pixel_ops = {
.set_rate = clk_edp_pixel_set_rate,
.set_rate_and_parent = clk_edp_pixel_set_rate_and_parent,
.determine_rate = clk_edp_pixel_determine_rate,
+ .list_registers = clk_rcg2_list_registers,
};
EXPORT_SYMBOL_GPL(clk_edp_pixel_ops);
@@ -615,6 +665,7 @@ const struct clk_ops clk_byte_ops = {
.set_rate = clk_byte_set_rate,
.set_rate_and_parent = clk_byte_set_rate_and_parent,
.determine_rate = clk_byte_determine_rate,
+ .list_registers = clk_rcg2_list_registers,
};
EXPORT_SYMBOL_GPL(clk_byte_ops);
@@ -685,6 +736,7 @@ const struct clk_ops clk_byte2_ops = {
.set_rate = clk_byte2_set_rate,
.set_rate_and_parent = clk_byte2_set_rate_and_parent,
.determine_rate = clk_byte2_determine_rate,
+ .list_registers = clk_rcg2_list_registers,
};
EXPORT_SYMBOL_GPL(clk_byte2_ops);
@@ -775,6 +827,7 @@ const struct clk_ops clk_pixel_ops = {
.set_rate = clk_pixel_set_rate,
.set_rate_and_parent = clk_pixel_set_rate_and_parent,
.determine_rate = clk_pixel_determine_rate,
+ .list_registers = clk_rcg2_list_registers,
};
EXPORT_SYMBOL_GPL(clk_pixel_ops);
@@ -864,6 +917,7 @@ const struct clk_ops clk_gfx3d_ops = {
.set_rate = clk_gfx3d_set_rate,
.set_rate_and_parent = clk_gfx3d_set_rate_and_parent,
.determine_rate = clk_gfx3d_determine_rate,
+ .list_registers = clk_rcg2_list_registers,
};
EXPORT_SYMBOL_GPL(clk_gfx3d_ops);
@@ -944,5 +998,7 @@ const struct clk_ops clk_gfx3d_src_ops = {
.set_rate = clk_gfx3d_set_rate,
.set_rate_and_parent = clk_gfx3d_src_set_rate_and_parent,
.determine_rate = clk_gfx3d_src_determine_rate,
+ .list_rate = clk_rcg2_list_rate,
+ .list_registers = clk_rcg2_list_registers,
};
EXPORT_SYMBOL_GPL(clk_gfx3d_src_ops);
diff --git a/drivers/clk/qcom/clk-regmap.h b/drivers/clk/qcom/clk-regmap.h
index 491a63d537df..8663dea02d79 100644
--- a/drivers/clk/qcom/clk-regmap.h
+++ b/drivers/clk/qcom/clk-regmap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2016, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -15,6 +15,7 @@
#define __QCOM_CLK_REGMAP_H__
#include <linux/clk-provider.h>
+#include <linux/debugfs.h>
struct regmap;
@@ -42,4 +43,9 @@ void clk_disable_regmap(struct clk_hw *hw);
struct clk *
devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk);
+struct clk_register_data {
+ char *name;
+ u32 offset;
+};
+
#endif
diff --git a/drivers/clk/qcom/gpucc-msmfalcon.c b/drivers/clk/qcom/gpucc-msmfalcon.c
index f194abb471cd..fe7cff443250 100644
--- a/drivers/clk/qcom/gpucc-msmfalcon.c
+++ b/drivers/clk/qcom/gpucc-msmfalcon.c
@@ -35,8 +35,8 @@
#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
#define F_GFX(f, s, h, m, n, sf) { (f), (s), (2 * (h) - 1), (m), (n), (sf) }
-static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner, NULL);
-static DEFINE_VDD_REGULATORS(vdd_mx, VDD_DIG_NUM, 1, vdd_corner, NULL);
+static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner);
+static DEFINE_VDD_REGULATORS(vdd_mx, VDD_DIG_NUM, 1, vdd_corner);
static DEFINE_VDD_REGS_INIT(vdd_gfx, 1);
enum {
@@ -181,6 +181,7 @@ static struct clk_init_data gpu_clks_init[] = {
* | 465000000 | 930000000 | 1 | 2 |
* | 588000000 | 1176000000 | 1 | 2 |
* | 647000000 | 1294000000 | 1 | 2 |
+ * | 700000000 | 1400000000 | 1 | 2 |
* | 750000000 | 1500000000 | 1 | 2 |
* ====================================================
*/
@@ -193,6 +194,7 @@ static const struct freq_tbl ftbl_gfx3d_clk_src[] = {
F_GFX(465000000, 0, 2, 0, 0, 930000000),
F_GFX(588000000, 0, 2, 0, 0, 1176000000),
F_GFX(647000000, 0, 2, 0, 0, 1294000000),
+ F_GFX(700000000, 0, 2, 0, 0, 1400000000),
F_GFX(750000000, 0, 2, 0, 0, 1500000000),
{ }
};
@@ -376,9 +378,9 @@ static int of_get_fmax_vdd_class(struct platform_device *pdev,
if (!vdd->vdd_uv)
return -ENOMEM;
- gpu_clks_init[index].fmax = devm_kzalloc(&pdev->dev, prop_len *
+ gpu_clks_init[index].rate_max = devm_kzalloc(&pdev->dev, prop_len *
sizeof(unsigned long), GFP_KERNEL);
- if (!gpu_clks_init[index].fmax)
+ if (!gpu_clks_init[index].rate_max)
return -ENOMEM;
array = devm_kzalloc(&pdev->dev, prop_len * sizeof(u32) * num,
@@ -388,7 +390,7 @@ static int of_get_fmax_vdd_class(struct platform_device *pdev,
of_property_read_u32_array(of, prop_name, array, prop_len * num);
for (i = 0; i < prop_len; i++) {
- gpu_clks_init[index].fmax[i] = array[num * i];
+ gpu_clks_init[index].rate_max[i] = array[num * i];
for (j = 1; j < num; j++) {
vdd->vdd_uv[(num - 1) * i + (j - 1)] =
array[num * i + j];
@@ -398,7 +400,7 @@ static int of_get_fmax_vdd_class(struct platform_device *pdev,
devm_kfree(&pdev->dev, array);
vdd->num_levels = prop_len;
vdd->cur_level = prop_len;
- gpu_clks_init[index].num_fmax = prop_len;
+ gpu_clks_init[index].num_rate_max = prop_len;
return 0;
}
diff --git a/drivers/cpufreq/qcom-cpufreq.c b/drivers/cpufreq/qcom-cpufreq.c
index 82861b1dbe46..2aa7b783f276 100644
--- a/drivers/cpufreq/qcom-cpufreq.c
+++ b/drivers/cpufreq/qcom-cpufreq.c
@@ -3,7 +3,7 @@
* MSM architecture cpufreq driver
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2007-2016, The Linux Foundation. All rights reserved.
* Author: Mike A. Chan <mikechan@google.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -320,7 +320,7 @@ static struct cpufreq_driver msm_cpufreq_driver = {
static struct cpufreq_frequency_table *cpufreq_parse_dt(struct device *dev,
char *tbl_name, int cpu)
{
- int ret, nf, i;
+ int ret, nf, i, j;
u32 *data;
struct cpufreq_frequency_table *ftbl;
@@ -344,6 +344,7 @@ static struct cpufreq_frequency_table *cpufreq_parse_dt(struct device *dev,
if (!ftbl)
return ERR_PTR(-ENOMEM);
+ j = 0;
for (i = 0; i < nf; i++) {
unsigned long f;
@@ -353,29 +354,20 @@ static struct cpufreq_frequency_table *cpufreq_parse_dt(struct device *dev,
f /= 1000;
/*
- * Check if this is the last feasible frequency in the table.
+ * Don't repeat frequencies if they round up to the same clock
+ * frequency.
*
- * The table listing frequencies higher than what the HW can
- * support is not an error since the table might be shared
- * across CPUs in different speed bins. It's also not
- * sufficient to check if the rounded rate is lower than the
- * requested rate as it doesn't cover the following example:
- *
- * Table lists: 2.2 GHz and 2.5 GHz.
- * Rounded rate returns: 2.2 GHz and 2.3 GHz.
- *
- * In this case, we can CPUfreq to use 2.2 GHz and 2.3 GHz
- * instead of rejecting the 2.5 GHz table entry.
*/
- if (i > 0 && f <= ftbl[i-1].frequency)
- break;
+ if (j > 0 && f <= ftbl[j - 1].frequency)
+ continue;
- ftbl[i].driver_data = i;
- ftbl[i].frequency = f;
+ ftbl[j].driver_data = j;
+ ftbl[j].frequency = f;
+ j++;
}
- ftbl[i].driver_data = i;
- ftbl[i].frequency = CPUFREQ_TABLE_END;
+ ftbl[j].driver_data = j;
+ ftbl[j].frequency = CPUFREQ_TABLE_END;
devm_kfree(dev, data);
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 3562de7fc967..55c043b44cea 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -3023,6 +3023,7 @@ static void qce_multireq_timeout(unsigned long data)
struct qce_device *pce_dev = (struct qce_device *)data;
int ret = 0;
int last_seq;
+ unsigned long flags;
last_seq = atomic_read(&pce_dev->bunch_cmd_seq);
if (last_seq == 0 ||
@@ -3032,21 +3033,33 @@ static void qce_multireq_timeout(unsigned long data)
return;
}
/* last bunch mode command time out */
+
+ /*
+ * From here to dummy request finish sps request and set owner back
+ * to none, we disable interrupt.
+ * So it won't get preempted or interrupted. If bam inerrupts happen
+ * between, and completion callback gets called from BAM, a new
+ * request may be issued by the client driver. Deadlock may happen.
+ */
+ local_irq_save(flags);
if (cmpxchg(&pce_dev->owner, QCE_OWNER_NONE, QCE_OWNER_TIMEOUT)
!= QCE_OWNER_NONE) {
+ local_irq_restore(flags);
mod_timer(&(pce_dev->timer), (jiffies + DELAY_IN_JIFFIES));
return;
}
- del_timer(&(pce_dev->timer));
- pce_dev->mode = IN_INTERRUPT_MODE;
- pce_dev->qce_stats.no_of_timeouts++;
- pr_debug("pcedev %d mode switch to INTR\n", pce_dev->dev_no);
ret = qce_dummy_req(pce_dev);
if (ret)
pr_warn("pcedev %d: Failed to insert dummy req\n",
pce_dev->dev_no);
cmpxchg(&pce_dev->owner, QCE_OWNER_TIMEOUT, QCE_OWNER_NONE);
+ pce_dev->mode = IN_INTERRUPT_MODE;
+ local_irq_restore(flags);
+
+ del_timer(&(pce_dev->timer));
+ pce_dev->qce_stats.no_of_timeouts++;
+ pr_debug("pcedev %d mode switch to INTR\n", pce_dev->dev_no);
}
void qce_get_driver_stats(void *handle)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index bc1c5f6dd4bd..844a8ad666a9 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -806,7 +806,7 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
struct devfreq *df = to_devfreq(dev);
int ret;
char str_governor[DEVFREQ_NAME_LEN + 1];
- struct devfreq_governor *governor;
+ const struct devfreq_governor *governor, *prev_gov;
ret = sscanf(buf, "%" __stringify(DEVFREQ_NAME_LEN) "s", str_governor);
if (ret != 1)
@@ -831,12 +831,21 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
goto out;
}
}
+ prev_gov = df->governor;
df->governor = governor;
strncpy(df->governor_name, governor->name, DEVFREQ_NAME_LEN);
ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
- if (ret)
+ if (ret) {
dev_warn(dev, "%s: Governor %s not started(%d)\n",
__func__, df->governor->name, ret);
+ if (prev_gov) {
+ df->governor = prev_gov;
+ strncpy(df->governor_name, prev_gov->name,
+ DEVFREQ_NAME_LEN);
+ df->governor->event_handler(df, DEVFREQ_GOV_START,
+ NULL);
+ }
+ }
out:
mutex_unlock(&devfreq_list_lock);
diff --git a/drivers/gpu/msm/a5xx_reg.h b/drivers/gpu/msm/a5xx_reg.h
index f3b4e6622043..ef2861ca96dd 100644
--- a/drivers/gpu/msm/a5xx_reg.h
+++ b/drivers/gpu/msm/a5xx_reg.h
@@ -608,6 +608,7 @@
#define A5XX_PC_PERFCTR_PC_SEL_7 0xD17
/* HLSQ registers */
+#define A5XX_HLSQ_DBG_ECO_CNTL 0xE04
#define A5XX_HLSQ_ADDR_MODE_CNTL 0xE05
#define A5XX_HLSQ_PERFCTR_HLSQ_SEL_0 0xE10
#define A5XX_HLSQ_PERFCTR_HLSQ_SEL_1 0xE11
@@ -632,6 +633,7 @@
#define A5XX_VFD_PERFCTR_VFD_SEL_7 0xE57
/* VPC registers */
+#define A5XX_VPC_DBG_ECO_CNTL 0xE60
#define A5XX_VPC_ADDR_MODE_CNTL 0xE61
#define A5XX_VPC_PERFCTR_VPC_SEL_0 0xE64
#define A5XX_VPC_PERFCTR_VPC_SEL_1 0xE65
@@ -891,6 +893,11 @@
#define A5XX_GDPM_INT_MASK 0xB811
#define A5XX_GPMU_BEC_ENABLE 0xB9A0
+/* ISENSE registers */
+#define A5XX_GPU_CS_DECIMAL_ALIGN 0xC16A
+#define A5XX_GPU_CS_SENSOR_PARAM_CORE_1 0xC126
+#define A5XX_GPU_CS_SENSOR_PARAM_CORE_2 0xC127
+#define A5XX_GPU_CS_SW_OV_FUSE_EN 0xC168
#define A5XX_GPU_CS_SENSOR_GENERAL_STATUS 0xC41A
#define A5XX_GPU_CS_AMP_CALIBRATION_STATUS1_0 0xC41D
#define A5XX_GPU_CS_AMP_CALIBRATION_STATUS1_2 0xC41F
@@ -898,5 +905,6 @@
#define A5XX_GPU_CS_ENABLE_REG 0xC520
#define A5XX_GPU_CS_AMP_CALIBRATION_CONTROL1 0xC557
#define A5XX_GPU_CS_AMP_CALIBRATION_DONE 0xC565
+#define A5XX_GPU_CS_ENDPOINT_CALIBRATION_DONE 0xC556
#endif /* _A5XX_REG_H */
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 6160aa567fbf..11226472d801 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -843,6 +843,8 @@ static struct {
{ ADRENO_QUIRK_FAULT_DETECT_MASK, "qcom,gpu-quirk-fault-detect-mask" },
{ ADRENO_QUIRK_DISABLE_RB_DP2CLOCKGATING,
"qcom,gpu-quirk-dp2clockgating-disable" },
+ { ADRENO_QUIRK_DISABLE_LMLOADKILL,
+ "qcom,gpu-quirk-lmloadkill-disable" },
};
static int adreno_of_get_power(struct adreno_device *adreno_dev,
@@ -2109,8 +2111,6 @@ static int adreno_soft_reset(struct kgsl_device *device)
adreno_support_64bit(adreno_dev))
gpudev->enable_64bit(adreno_dev);
- /* Restore physical performance counter values after soft reset */
- adreno_perfcounter_restore(adreno_dev);
/* Reinitialize the GPU */
gpudev->start(adreno_dev);
@@ -2137,6 +2137,9 @@ static int adreno_soft_reset(struct kgsl_device *device)
set_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv);
}
+ /* Restore physical performance counter values after soft reset */
+ adreno_perfcounter_restore(adreno_dev);
+
return ret;
}
@@ -2291,9 +2294,9 @@ static void adreno_read(struct kgsl_device *device, void __iomem *base,
unsigned int mem_len)
{
- unsigned int __iomem *reg;
+ void __iomem *reg;
BUG_ON(offsetwords*sizeof(uint32_t) >= mem_len);
- reg = (unsigned int __iomem *)(base + (offsetwords << 2));
+ reg = (base + (offsetwords << 2));
if (!in_interrupt())
kgsl_pre_hwaccess(device);
@@ -2333,7 +2336,7 @@ static void adreno_regwrite(struct kgsl_device *device,
unsigned int offsetwords,
unsigned int value)
{
- unsigned int __iomem *reg;
+ void __iomem *reg;
BUG_ON(offsetwords*sizeof(uint32_t) >= device->reg_len);
@@ -2343,7 +2346,7 @@ static void adreno_regwrite(struct kgsl_device *device,
trace_kgsl_regwrite(device, offsetwords, value);
kgsl_cffdump_regwrite(device, offsetwords << 2, value);
- reg = (unsigned int __iomem *)(device->reg_virt + (offsetwords << 2));
+ reg = (device->reg_virt + (offsetwords << 2));
/*ensure previous writes post before this one,
* i.e. act like normal writel() */
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index a2af26c81f50..d81142db5b58 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -123,6 +123,8 @@
#define ADRENO_QUIRK_FAULT_DETECT_MASK BIT(3)
/* Disable RB sampler datapath clock gating optimization */
#define ADRENO_QUIRK_DISABLE_RB_DP2CLOCKGATING BIT(4)
+/* Disable local memory(LM) feature to avoid corner case error */
+#define ADRENO_QUIRK_DISABLE_LMLOADKILL BIT(5)
/* Flags to control command packet settings */
#define KGSL_CMD_FLAGS_NONE 0
diff --git a/drivers/gpu/msm/adreno_a4xx_preempt.c b/drivers/gpu/msm/adreno_a4xx_preempt.c
index 4087ac60c89e..ef837dc4b7ea 100644
--- a/drivers/gpu/msm/adreno_a4xx_preempt.c
+++ b/drivers/gpu/msm/adreno_a4xx_preempt.c
@@ -146,6 +146,8 @@ static int a4xx_submit_preempt_token(struct adreno_ringbuffer *rb,
&ptname, PT_INFO_OFFSET(current_rb_ptname));
pt = kgsl_mmu_get_pt_from_ptname(&(device->mmu),
ptname);
+ if (IS_ERR_OR_NULL(pt))
+ return (pt == NULL) ? -ENOENT : PTR_ERR(pt);
/* set the ringbuffer for incoming RB */
pt_switch_sizedwords =
adreno_iommu_set_pt_generate_cmds(incoming_rb,
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c
index 860f6d2925f1..dc35c0080d11 100644
--- a/drivers/gpu/msm/adreno_a5xx.c
+++ b/drivers/gpu/msm/adreno_a5xx.c
@@ -196,6 +196,8 @@ static void a5xx_platform_setup(struct adreno_device *adreno_dev)
/* A510 has 3 XIN ports in VBIF */
gpudev->vbif_xin_halt_ctrl0_mask =
A510_VBIF_XIN_HALT_CTRL0_MASK;
+ } else if (adreno_is_a540(adreno_dev)) {
+ gpudev->snapshot_data->sect_sizes->cp_merciu = 1024;
}
/* Calculate SP local and private mem addresses */
@@ -252,7 +254,7 @@ static int a5xx_critical_packet_construct(struct adreno_device *adreno_dev)
return ret;
ret = kgsl_allocate_user(&adreno_dev->dev, &crit_pkts_refbuf0,
- NULL, PAGE_SIZE, KGSL_MEMFLAGS_SECURE);
+ PAGE_SIZE, KGSL_MEMFLAGS_SECURE);
if (ret)
return ret;
@@ -429,6 +431,43 @@ static int _poll_gdsc_status(struct adreno_device *adreno_dev,
return 0;
}
+static void a5xx_restore_isense_regs(struct adreno_device *adreno_dev)
+{
+ struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
+ unsigned int reg, i, ramp = GPMU_ISENSE_SAVE;
+ static unsigned int isense_regs[6] = {0xFFFF}, isense_reg_addr[] = {
+ A5XX_GPU_CS_DECIMAL_ALIGN,
+ A5XX_GPU_CS_SENSOR_PARAM_CORE_1,
+ A5XX_GPU_CS_SENSOR_PARAM_CORE_2,
+ A5XX_GPU_CS_SW_OV_FUSE_EN,
+ A5XX_GPU_CS_ENDPOINT_CALIBRATION_DONE,
+ A5XX_GPMU_TEMP_SENSOR_CONFIG};
+
+ if (!adreno_is_a540(adreno_dev))
+ return;
+
+ /* read signature */
+ kgsl_regread(device, ramp++, &reg);
+
+ if (reg == 0xBABEFACE) {
+ /* store memory locations in buffer */
+ for (i = 0; i < ARRAY_SIZE(isense_regs); i++)
+ kgsl_regread(device, ramp + i, isense_regs + i);
+
+ /* clear signature */
+ kgsl_regwrite(device, GPMU_ISENSE_SAVE, 0x0);
+ }
+
+ /* if we never stored memory locations - do nothing */
+ if (isense_regs[0] == 0xFFFF)
+ return;
+
+ /* restore registers from memory */
+ for (i = 0; i < ARRAY_SIZE(isense_reg_addr); i++)
+ kgsl_regwrite(device, isense_reg_addr[i], isense_regs[i]);
+
+}
+
/*
* a5xx_regulator_enable() - Enable any necessary HW regulators
* @adreno_dev: The adreno device pointer
@@ -478,6 +517,7 @@ static int a5xx_regulator_enable(struct adreno_device *adreno_dev)
kgsl_regrmw(device, A5XX_GPMU_GPMU_SP_CLOCK_CONTROL,
CNTL_IP_CLK_ENABLE, 1);
+ a5xx_restore_isense_regs(adreno_dev);
return 0;
}
@@ -1534,12 +1574,12 @@ static void a5xx_clk_set_options(struct adreno_device *adreno_dev,
const char *name, struct clk *clk)
{
if (adreno_is_a540(adreno_dev)) {
- if (!strcmp(name, "mem_iface_clk"))
- clk_set_flags(clk, CLKFLAG_NORETAIN_PERIPH);
- clk_set_flags(clk, CLKFLAG_NORETAIN_MEM);
- if (!strcmp(name, "core_clk")) {
+ if (!strcmp(name, "mem_iface_clk")) {
clk_set_flags(clk, CLKFLAG_NORETAIN_PERIPH);
clk_set_flags(clk, CLKFLAG_NORETAIN_MEM);
+ } else if (!strcmp(name, "core_clk")) {
+ clk_set_flags(clk, CLKFLAG_RETAIN_PERIPH);
+ clk_set_flags(clk, CLKFLAG_RETAIN_MEM);
}
}
}
@@ -1781,11 +1821,11 @@ static void a5xx_start(struct adreno_device *adreno_dev)
set_bit(ADRENO_DEVICE_HANG_INTR, &adreno_dev->priv);
gpudev->irq->mask |= (1 << A5XX_INT_MISC_HANG_DETECT);
/*
- * Set hang detection threshold to 1 million cycles
- * (0xFFFF*16)
+ * Set hang detection threshold to 4 million cycles
+ * (0x3FFFF*16)
*/
kgsl_regwrite(device, A5XX_RBBM_INTERFACE_HANG_INT_CNTL,
- (1 << 30) | 0xFFFF);
+ (1 << 30) | 0x3FFFF);
}
@@ -1944,6 +1984,16 @@ static void a5xx_start(struct adreno_device *adreno_dev)
}
+ /*
+ * VPC corner case with local memory load kill leads to corrupt
+ * internal state. Normal Disable does not work for all a5x chips.
+ * So do the following setting to disable it.
+ */
+ if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_DISABLE_LMLOADKILL)) {
+ kgsl_regrmw(device, A5XX_VPC_DBG_ECO_CNTL, 0, 0x1 << 23);
+ kgsl_regrmw(device, A5XX_HLSQ_DBG_ECO_CNTL, 0x1 << 18, 0);
+ }
+
a5xx_preemption_start(adreno_dev);
a5xx_protect_init(adreno_dev);
}
diff --git a/drivers/gpu/msm/adreno_a5xx.h b/drivers/gpu/msm/adreno_a5xx.h
index e424e7a9f228..08fd16a83f30 100644
--- a/drivers/gpu/msm/adreno_a5xx.h
+++ b/drivers/gpu/msm/adreno_a5xx.h
@@ -228,6 +228,7 @@ void a5xx_hwcg_set(struct adreno_device *adreno_dev, bool on);
#define LM_SEQUENCE_ID 1
#define MAX_SEQUENCE_ID 3
+#define GPMU_ISENSE_SAVE (A5XX_GPMU_DATA_RAM_BASE + 200/4)
/* LM defaults */
#define LM_DEFAULT_LIMIT 6000
#define A530_DEFAULT_LEAKAGE 0x004E001A
diff --git a/drivers/gpu/msm/adreno_perfcounter.c b/drivers/gpu/msm/adreno_perfcounter.c
index 42f8119ad8b4..f5f99c3ebb4a 100644
--- a/drivers/gpu/msm/adreno_perfcounter.c
+++ b/drivers/gpu/msm/adreno_perfcounter.c
@@ -522,12 +522,18 @@ int adreno_perfcounter_get(struct adreno_device *adreno_dev,
if (empty == -1)
return -EBUSY;
+ /* initialize the new counter */
+ group->regs[empty].countable = countable;
+
/* enable the new counter */
ret = adreno_perfcounter_enable(adreno_dev, groupid, empty, countable);
- if (ret)
+ if (ret) {
+ /* Put back the perfcounter */
+ if (!(group->flags & ADRENO_PERFCOUNTER_GROUP_FIXED))
+ group->regs[empty].countable =
+ KGSL_PERFCOUNTER_NOT_USED;
return ret;
- /* initialize the new counter */
- group->regs[empty].countable = countable;
+ }
/* set initial kernel and user count */
if (flags & PERFCOUNTER_FLAG_KERNEL) {
@@ -720,10 +726,22 @@ static int _perfcounter_enable_default(struct adreno_device *adreno_dev,
/* wait for the above commands submitted to complete */
ret = adreno_ringbuffer_waittimestamp(rb, rb->timestamp,
ADRENO_IDLE_TIMEOUT);
- if (ret)
- KGSL_DRV_ERR(device,
- "Perfcounter %u/%u/%u start via commands failed %d\n",
- group, counter, countable, ret);
+ if (ret) {
+ /*
+ * If we were woken up because of cancelling rb events
+ * either due to soft reset or adreno_stop, ignore the
+ * error and return 0 here. The perfcounter is already
+ * set up in software and it will be programmed in
+ * hardware when we wake up or come up after soft reset,
+ * by adreno_perfcounter_restore.
+ */
+ if (ret == -EAGAIN)
+ ret = 0;
+ else
+ KGSL_DRV_ERR(device,
+ "Perfcounter %u/%u/%u start via commands failed %d\n",
+ group, counter, countable, ret);
+ }
} else {
/* Select the desired perfcounter */
kgsl_regwrite(device, reg->select, countable);
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index fe0715629825..699d99651f2c 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -176,9 +176,10 @@ int kgsl_memfree_find_entry(pid_t ptname, uint64_t *gpuaddr,
return 0;
}
-static void kgsl_memfree_purge(pid_t ptname, uint64_t gpuaddr,
- uint64_t size)
+static void kgsl_memfree_purge(struct kgsl_pagetable *pagetable,
+ uint64_t gpuaddr, uint64_t size)
{
+ pid_t ptname = pagetable ? pagetable->name : 0;
int i;
if (memfree.list == NULL)
@@ -342,60 +343,24 @@ kgsl_mem_entry_destroy(struct kref *kref)
}
EXPORT_SYMBOL(kgsl_mem_entry_destroy);
-/**
- * kgsl_mem_entry_track_gpuaddr - Insert a mem_entry in the address tree and
- * assign it with a gpu address space before insertion
- * @process: the process that owns the memory
- * @entry: the memory entry
- *
- * @returns - 0 on succcess else error code
- *
- * Insert the kgsl_mem_entry in to the rb_tree for searching by GPU address.
- * The assignment of gpu address and insertion into list needs to
- * happen with the memory lock held to avoid race conditions between
- * gpu address being selected and some other thread looking through the
- * rb list in search of memory based on gpuaddr
- * This function should be called with processes memory spinlock held
- */
-static int
-kgsl_mem_entry_track_gpuaddr(struct kgsl_process_private *process,
- struct kgsl_mem_entry *entry)
+/* Allocate a IOVA for memory objects that don't use SVM */
+static int kgsl_mem_entry_track_gpuaddr(struct kgsl_device *device,
+ struct kgsl_process_private *process,
+ struct kgsl_mem_entry *entry)
{
- struct kgsl_pagetable *pagetable = process->pagetable;
+ struct kgsl_pagetable *pagetable;
/*
- * If cpu=gpu map is used then caller needs to set the
- * gpu address
+ * If SVM is enabled for this object then the address needs to be
+ * assigned elsewhere
*/
- if (kgsl_memdesc_use_cpu_map(&entry->memdesc)) {
- if (!entry->memdesc.gpuaddr)
- return 0;
- } else if (entry->memdesc.gpuaddr) {
- WARN_ONCE(1, "gpuaddr assigned w/o holding memory lock\n");
- return -EINVAL;
- }
- if (kgsl_memdesc_is_secured(&entry->memdesc))
- pagetable = pagetable->mmu->securepagetable;
+ if (kgsl_memdesc_use_cpu_map(&entry->memdesc))
+ return 0;
- return kgsl_mmu_get_gpuaddr(pagetable, &entry->memdesc);
-}
+ pagetable = kgsl_memdesc_is_secured(&entry->memdesc) ?
+ device->mmu.securepagetable : process->pagetable;
-/**
- * kgsl_mem_entry_untrack_gpuaddr() - Untrack memory that is previously tracked
- * process - Pointer to process private to which memory belongs
- * entry - Memory entry to untrack
- *
- * Function just does the opposite of kgsl_mem_entry_track_gpuaddr. Needs to be
- * called with processes spin lock held
- */
-static void
-kgsl_mem_entry_untrack_gpuaddr(struct kgsl_process_private *process,
- struct kgsl_mem_entry *entry)
-{
- struct kgsl_pagetable *pagetable = entry->memdesc.pagetable;
-
- if (entry->memdesc.gpuaddr)
- kgsl_mmu_put_gpuaddr(pagetable, &entry->memdesc);
+ return kgsl_mmu_get_gpuaddr(pagetable, &entry->memdesc);
}
/* Commit the entry to the process so it can be accessed by other operations */
@@ -409,33 +374,25 @@ static void kgsl_mem_entry_commit_process(struct kgsl_mem_entry *entry)
spin_unlock(&entry->priv->mem_lock);
}
-/**
- * kgsl_mem_entry_attach_process - Attach a mem_entry to its owner process
- * @entry: the memory entry
- * @process: the owner process
- *
- * Attach a newly created mem_entry to its owner process so that
- * it can be found later. The mem_entry will be added to mem_idr and have
- * its 'id' field assigned.
- *
- * @returns - 0 on success or error code on failure.
+/*
+ * Attach the memory object to a process by (possibly) getting a GPU address and
+ * (possibly) mapping it
*/
-int
-kgsl_mem_entry_attach_process(struct kgsl_mem_entry *entry,
- struct kgsl_device_private *dev_priv)
+static int kgsl_mem_entry_attach_process(struct kgsl_device *device,
+ struct kgsl_process_private *process,
+ struct kgsl_mem_entry *entry)
{
- int id;
- int ret;
- struct kgsl_process_private *process = dev_priv->process_priv;
- struct kgsl_pagetable *pagetable = NULL;
+ int id, ret;
ret = kgsl_process_private_get(process);
if (!ret)
return -EBADF;
- ret = kgsl_mem_entry_track_gpuaddr(process, entry);
- if (ret)
- goto err_put_proc_priv;
+ ret = kgsl_mem_entry_track_gpuaddr(device, process, entry);
+ if (ret) {
+ kgsl_process_private_put(process);
+ return ret;
+ }
idr_preload(GFP_KERNEL);
spin_lock(&process->mem_lock);
@@ -445,47 +402,44 @@ kgsl_mem_entry_attach_process(struct kgsl_mem_entry *entry,
idr_preload_end();
if (id < 0) {
- ret = id;
- kgsl_mem_entry_untrack_gpuaddr(process, entry);
- goto err_put_proc_priv;
+ if (!kgsl_memdesc_use_cpu_map(&entry->memdesc))
+ kgsl_mmu_put_gpuaddr(&entry->memdesc);
+ kgsl_process_private_put(process);
+ return id;
}
entry->id = id;
entry->priv = process;
- /* map the memory after unlocking if gpuaddr has been assigned */
+ /*
+ * Map the memory if a GPU address is already assigned, either through
+ * kgsl_mem_entry_track_gpuaddr() or via some other SVM process
+ */
if (entry->memdesc.gpuaddr) {
- pagetable = process->pagetable;
- if (kgsl_memdesc_is_secured(&entry->memdesc))
- pagetable = pagetable->mmu->securepagetable;
-
- entry->memdesc.pagetable = pagetable;
-
if (entry->memdesc.flags & KGSL_MEMFLAGS_SPARSE_VIRT)
- ret = kgsl_mmu_sparse_dummy_map(pagetable,
- &entry->memdesc, 0, entry->memdesc.size);
+ ret = kgsl_mmu_sparse_dummy_map(
+ entry->memdesc.pagetable,
+ &entry->memdesc, 0,
+ entry->memdesc.size);
else if (entry->memdesc.gpuaddr)
- ret = kgsl_mmu_map(pagetable, &entry->memdesc);
+ ret = kgsl_mmu_map(entry->memdesc.pagetable,
+ &entry->memdesc);
+
if (ret)
kgsl_mem_entry_detach_process(entry);
}
- kgsl_memfree_purge(pagetable ? pagetable->name : 0,
- entry->memdesc.gpuaddr, entry->memdesc.size);
-
- return ret;
+ kgsl_memfree_purge(entry->memdesc.pagetable, entry->memdesc.gpuaddr,
+ entry->memdesc.size);
-err_put_proc_priv:
- kgsl_process_private_put(process);
return ret;
}
/* Detach a memory entry from a process and unmap it from the MMU */
-
static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry)
{
unsigned int type;
- int ret;
+
if (entry == NULL)
return;
@@ -502,14 +456,7 @@ static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry)
entry->priv->stats[type].cur -= entry->memdesc.size;
spin_unlock(&entry->priv->mem_lock);
- ret = kgsl_mmu_unmap(entry->memdesc.pagetable, &entry->memdesc);
- /*
- * Do not free the gpuaddr/size if unmap fails. Because if we try
- * to map this range in future, the iommu driver will throw
- * a BUG_ON() because it feels we are overwriting a mapping.
- */
- if (ret == 0)
- kgsl_mem_entry_untrack_gpuaddr(entry->priv, entry);
+ kgsl_mmu_put_gpuaddr(&entry->memdesc);
kgsl_process_private_put(entry->priv);
@@ -2139,10 +2086,21 @@ static int kgsl_setup_anon_useraddr(struct kgsl_pagetable *pagetable,
entry->memdesc.pagetable = pagetable;
entry->memdesc.size = (uint64_t) size;
entry->memdesc.useraddr = hostptr;
- if (kgsl_memdesc_use_cpu_map(&entry->memdesc))
- entry->memdesc.gpuaddr = (uint64_t) entry->memdesc.useraddr;
entry->memdesc.flags |= KGSL_MEMFLAGS_USERMEM_ADDR;
+ if (kgsl_memdesc_use_cpu_map(&entry->memdesc)) {
+ int ret;
+
+ /* Register the address in the database */
+ ret = kgsl_mmu_set_svm_region(pagetable,
+ (uint64_t) entry->memdesc.useraddr, (uint64_t) size);
+
+ if (ret)
+ return ret;
+
+ entry->memdesc.gpuaddr = (uint64_t) entry->memdesc.useraddr;
+ }
+
return memdesc_sg_virt(&entry->memdesc, NULL);
}
@@ -2392,7 +2350,7 @@ long kgsl_ioctl_gpuobj_import(struct kgsl_device_private *dev_priv,
param->flags = entry->memdesc.flags;
- ret = kgsl_mem_entry_attach_process(entry, dev_priv);
+ ret = kgsl_mem_entry_attach_process(dev_priv->device, private, entry);
if (ret)
goto unmap;
@@ -2507,6 +2465,8 @@ static int kgsl_setup_dma_buf(struct kgsl_device *device,
meta->dmabuf = dmabuf;
meta->attach = attach;
+ attach->priv = entry;
+
entry->priv_data = meta;
entry->memdesc.pagetable = pagetable;
entry->memdesc.size = 0;
@@ -2557,6 +2517,45 @@ out:
}
#endif
+#ifdef CONFIG_DMA_SHARED_BUFFER
+void kgsl_get_egl_counts(struct kgsl_mem_entry *entry,
+ int *egl_surface_count, int *egl_image_count)
+{
+ struct kgsl_dma_buf_meta *meta = entry->priv_data;
+ struct dma_buf *dmabuf = meta->dmabuf;
+ struct dma_buf_attachment *mem_entry_buf_attachment = meta->attach;
+ struct device *buf_attachment_dev = mem_entry_buf_attachment->dev;
+ struct dma_buf_attachment *attachment = NULL;
+
+ mutex_lock(&dmabuf->lock);
+ list_for_each_entry(attachment, &dmabuf->attachments, node) {
+ struct kgsl_mem_entry *scan_mem_entry = NULL;
+
+ if (attachment->dev != buf_attachment_dev)
+ continue;
+
+ scan_mem_entry = attachment->priv;
+ if (!scan_mem_entry)
+ continue;
+
+ switch (kgsl_memdesc_get_memtype(&scan_mem_entry->memdesc)) {
+ case KGSL_MEMTYPE_EGL_SURFACE:
+ (*egl_surface_count)++;
+ break;
+ case KGSL_MEMTYPE_EGL_IMAGE:
+ (*egl_image_count)++;
+ break;
+ }
+ }
+ mutex_unlock(&dmabuf->lock);
+}
+#else
+void kgsl_get_egl_counts(struct kgsl_mem_entry *entry,
+ int *egl_surface_count, int *egl_image_count)
+{
+}
+#endif
+
long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv,
unsigned int cmd, void *data)
{
@@ -2655,7 +2654,8 @@ long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv,
/* echo back flags */
param->flags = (unsigned int) entry->memdesc.flags;
- result = kgsl_mem_entry_attach_process(entry, dev_priv);
+ result = kgsl_mem_entry_attach_process(dev_priv->device, private,
+ entry);
if (result)
goto error_attach;
@@ -3048,11 +3048,11 @@ static struct kgsl_mem_entry *gpumem_alloc_entry(
entry->memdesc.priv |= KGSL_MEMDESC_SECURE;
ret = kgsl_allocate_user(dev_priv->device, &entry->memdesc,
- private->pagetable, size, flags);
+ size, flags);
if (ret != 0)
goto err;
- ret = kgsl_mem_entry_attach_process(entry, dev_priv);
+ ret = kgsl_mem_entry_attach_process(dev_priv->device, private, entry);
if (ret != 0) {
kgsl_sharedmem_free(&entry->memdesc);
goto err;
@@ -3251,7 +3251,7 @@ long kgsl_ioctl_sparse_phys_alloc(struct kgsl_device_private *dev_priv,
kgsl_memdesc_set_align(&entry->memdesc, ilog2(param->pagesize));
ret = kgsl_allocate_user(dev_priv->device, &entry->memdesc,
- process->pagetable, param->size, entry->memdesc.flags);
+ param->size, entry->memdesc.flags);
if (ret)
goto err_remove_idr;
@@ -3318,6 +3318,7 @@ long kgsl_ioctl_sparse_phys_free(struct kgsl_device_private *dev_priv,
long kgsl_ioctl_sparse_virt_alloc(struct kgsl_device_private *dev_priv,
unsigned int cmd, void *data)
{
+ struct kgsl_process_private *private = dev_priv->process_priv;
struct kgsl_sparse_virt_alloc *param = data;
struct kgsl_mem_entry *entry;
int ret;
@@ -3338,7 +3339,7 @@ long kgsl_ioctl_sparse_virt_alloc(struct kgsl_device_private *dev_priv,
spin_lock_init(&entry->bind_lock);
entry->bind_tree = RB_ROOT;
- ret = kgsl_mem_entry_attach_process(entry, dev_priv);
+ ret = kgsl_mem_entry_attach_process(dev_priv->device, private, entry);
if (ret) {
kfree(entry);
return ret;
@@ -3891,7 +3892,7 @@ kgsl_mmap_memstore(struct kgsl_device *device, struct vm_area_struct *vma)
return -EINVAL;
}
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
result = remap_pfn_range(vma, vma->vm_start,
device->memstore.physaddr >> PAGE_SHIFT,
@@ -4016,16 +4017,16 @@ static unsigned long _gpu_set_svm_region(struct kgsl_process_private *private,
return ret;
entry->memdesc.gpuaddr = (uint64_t) addr;
+ entry->memdesc.pagetable = private->pagetable;
ret = kgsl_mmu_map(private->pagetable, &entry->memdesc);
if (ret) {
- kgsl_mmu_put_gpuaddr(private->pagetable,
- &entry->memdesc);
+ kgsl_mmu_put_gpuaddr(&entry->memdesc);
return ret;
}
- kgsl_memfree_purge(private->pagetable ? private->pagetable->name : 0,
- entry->memdesc.gpuaddr, entry->memdesc.size);
+ kgsl_memfree_purge(private->pagetable, entry->memdesc.gpuaddr,
+ entry->memdesc.size);
return addr;
}
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index 826c4edb3582..fbf9197b6d1b 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -435,6 +435,9 @@ long kgsl_ioctl_sparse_unbind(struct kgsl_device_private *dev_priv,
void kgsl_mem_entry_destroy(struct kref *kref);
+void kgsl_get_egl_counts(struct kgsl_mem_entry *entry,
+ int *egl_surface_count, int *egl_image_count);
+
struct kgsl_mem_entry * __must_check
kgsl_sharedmem_find(struct kgsl_process_private *private, uint64_t gpuaddr);
diff --git a/drivers/gpu/msm/kgsl_debugfs.c b/drivers/gpu/msm/kgsl_debugfs.c
index 2f293e4da398..7758fc956055 100644
--- a/drivers/gpu/msm/kgsl_debugfs.c
+++ b/drivers/gpu/msm/kgsl_debugfs.c
@@ -125,13 +125,15 @@ static char get_cacheflag(const struct kgsl_memdesc *m)
}
-static int print_mem_entry(int id, void *ptr, void *data)
+static int print_mem_entry(void *data, void *ptr)
{
struct seq_file *s = data;
struct kgsl_mem_entry *entry = ptr;
char flags[10];
char usage[16];
struct kgsl_memdesc *m = &entry->memdesc;
+ unsigned int usermem_type = kgsl_memdesc_usermem_type(m);
+ int egl_surface_count = 0, egl_image_count = 0;
if (m->flags & KGSL_MEMFLAGS_SPARSE_VIRT)
return 0;
@@ -149,12 +151,17 @@ static int print_mem_entry(int id, void *ptr, void *data)
kgsl_get_memory_usage(usage, sizeof(usage), m->flags);
- seq_printf(s, "%pK %pK %16llu %5d %9s %10s %16s %5d %16llu",
+ if (usermem_type == KGSL_MEM_ENTRY_ION)
+ kgsl_get_egl_counts(entry, &egl_surface_count,
+ &egl_image_count);
+
+ seq_printf(s, "%pK %pK %16llu %5d %9s %10s %16s %5d %16llu %6d %6d",
(uint64_t *)(uintptr_t) m->gpuaddr,
(unsigned long *) m->useraddr,
m->size, entry->id, flags,
- memtype_str(kgsl_memdesc_usermem_type(m)),
- usage, (m->sgt ? m->sgt->nents : 0), m->mapsize);
+ memtype_str(usermem_type),
+ usage, (m->sgt ? m->sgt->nents : 0), m->mapsize,
+ egl_surface_count, egl_image_count);
if (entry->metadata[0] != 0)
seq_printf(s, " %s", entry->metadata);
@@ -164,25 +171,83 @@ static int print_mem_entry(int id, void *ptr, void *data)
return 0;
}
-static int process_mem_print(struct seq_file *s, void *unused)
+static struct kgsl_mem_entry *process_mem_seq_find(struct seq_file *s,
+ void *ptr, loff_t pos)
{
+ struct kgsl_mem_entry *entry = ptr;
struct kgsl_process_private *private = s->private;
+ int id = 0;
+ loff_t temp_pos = 1;
- seq_printf(s, "%16s %16s %16s %5s %9s %10s %16s %5s %16s\n",
- "gpuaddr", "useraddr", "size", "id", "flags", "type",
- "usage", "sglen", "mapsize");
+ if (entry != SEQ_START_TOKEN)
+ id = entry->id + 1;
spin_lock(&private->mem_lock);
- idr_for_each(&private->mem_idr, print_mem_entry, s);
+ for (entry = idr_get_next(&private->mem_idr, &id); entry;
+ id++, entry = idr_get_next(&private->mem_idr, &id),
+ temp_pos++) {
+ if (temp_pos == pos && kgsl_mem_entry_get(entry)) {
+ spin_unlock(&private->mem_lock);
+ goto found;
+ }
+ }
spin_unlock(&private->mem_lock);
- return 0;
+ entry = NULL;
+found:
+ if (ptr != SEQ_START_TOKEN)
+ kgsl_mem_entry_put(ptr);
+
+ return entry;
+}
+
+static void *process_mem_seq_start(struct seq_file *s, loff_t *pos)
+{
+ loff_t seq_file_offset = *pos;
+
+ if (seq_file_offset == 0)
+ return SEQ_START_TOKEN;
+ else
+ return process_mem_seq_find(s, SEQ_START_TOKEN,
+ seq_file_offset);
+}
+
+static void process_mem_seq_stop(struct seq_file *s, void *ptr)
+{
+ if (ptr && ptr != SEQ_START_TOKEN)
+ kgsl_mem_entry_put(ptr);
}
+static void *process_mem_seq_next(struct seq_file *s, void *ptr,
+ loff_t *pos)
+{
+ ++*pos;
+ return process_mem_seq_find(s, ptr, 1);
+}
+
+static int process_mem_seq_show(struct seq_file *s, void *ptr)
+{
+ if (ptr == SEQ_START_TOKEN) {
+ seq_printf(s, "%16s %16s %16s %5s %9s %10s %16s %5s %16s %6s %6s\n",
+ "gpuaddr", "useraddr", "size", "id", "flags", "type",
+ "usage", "sglen", "mapsize", "eglsrf", "eglimg");
+ return 0;
+ } else
+ return print_mem_entry(s, ptr);
+}
+
+static const struct seq_operations process_mem_seq_fops = {
+ .start = process_mem_seq_start,
+ .stop = process_mem_seq_stop,
+ .next = process_mem_seq_next,
+ .show = process_mem_seq_show,
+};
+
static int process_mem_open(struct inode *inode, struct file *file)
{
int ret;
pid_t pid = (pid_t) (unsigned long) inode->i_private;
+ struct seq_file *s = NULL;
struct kgsl_process_private *private = NULL;
private = kgsl_process_private_find(pid);
@@ -190,9 +255,13 @@ static int process_mem_open(struct inode *inode, struct file *file)
if (!private)
return -ENODEV;
- ret = single_open(file, process_mem_print, private);
+ ret = seq_open(file, &process_mem_seq_fops);
if (ret)
kgsl_process_private_put(private);
+ else {
+ s = file->private_data;
+ s->private = private;
+ }
return ret;
}
@@ -205,7 +274,7 @@ static int process_mem_release(struct inode *inode, struct file *file)
if (private)
kgsl_process_private_put(private);
- return single_release(inode, file);
+ return seq_release(inode, file);
}
static const struct file_operations process_mem_fops = {
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 9f35a3197a4c..bc681057250d 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -1403,17 +1403,16 @@ static int _setstate_alloc(struct kgsl_device *device,
{
int ret;
- ret = kgsl_sharedmem_alloc_contig(device, &iommu->setstate, NULL,
- PAGE_SIZE);
- if (ret)
- return ret;
+ ret = kgsl_sharedmem_alloc_contig(device, &iommu->setstate, PAGE_SIZE);
- /* Mark the setstate memory as read only */
- iommu->setstate.flags |= KGSL_MEMFLAGS_GPUREADONLY;
+ if (!ret) {
+ /* Mark the setstate memory as read only */
+ iommu->setstate.flags |= KGSL_MEMFLAGS_GPUREADONLY;
- kgsl_sharedmem_set(device, &iommu->setstate, 0, 0, PAGE_SIZE);
+ kgsl_sharedmem_set(device, &iommu->setstate, 0, 0, PAGE_SIZE);
+ }
- return 0;
+ return ret;
}
static int kgsl_iommu_init(struct kgsl_mmu *mmu)
@@ -1663,7 +1662,7 @@ static int _iommu_map_guard_page(struct kgsl_pagetable *pt,
if (!kgsl_secure_guard_page_memdesc.sgt) {
if (kgsl_allocate_user(KGSL_MMU_DEVICE(pt->mmu),
- &kgsl_secure_guard_page_memdesc, pt,
+ &kgsl_secure_guard_page_memdesc,
sgp_size, KGSL_MEMFLAGS_SECURE)) {
KGSL_CORE_ERR(
"Secure guard page alloc failed\n");
@@ -2364,23 +2363,27 @@ static int kgsl_iommu_get_gpuaddr(struct kgsl_pagetable *pagetable,
}
ret = _insert_gpuaddr(pagetable, addr, size);
- if (ret == 0)
+ if (ret == 0) {
memdesc->gpuaddr = addr;
+ memdesc->pagetable = pagetable;
+ }
out:
spin_unlock(&pagetable->lock);
return ret;
}
-static void kgsl_iommu_put_gpuaddr(struct kgsl_pagetable *pagetable,
- struct kgsl_memdesc *memdesc)
+static void kgsl_iommu_put_gpuaddr(struct kgsl_memdesc *memdesc)
{
- spin_lock(&pagetable->lock);
+ if (memdesc->pagetable == NULL)
+ return;
+
+ spin_lock(&memdesc->pagetable->lock);
- if (_remove_gpuaddr(pagetable, memdesc->gpuaddr))
+ if (_remove_gpuaddr(memdesc->pagetable, memdesc->gpuaddr))
BUG();
- spin_unlock(&pagetable->lock);
+ spin_unlock(&memdesc->pagetable->lock);
}
static int kgsl_iommu_svm_range(struct kgsl_pagetable *pagetable,
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index f516b7cd245a..46bb6f4656fb 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -424,17 +424,29 @@ EXPORT_SYMBOL(kgsl_mmu_map);
* @pagetable: Pagetable to release the memory from
* @memdesc: Memory descriptor containing the GPU address to free
*/
-void kgsl_mmu_put_gpuaddr(struct kgsl_pagetable *pagetable,
- struct kgsl_memdesc *memdesc)
+void kgsl_mmu_put_gpuaddr(struct kgsl_memdesc *memdesc)
{
+ struct kgsl_pagetable *pagetable = memdesc->pagetable;
+ int unmap_fail = 0;
+
if (memdesc->size == 0 || memdesc->gpuaddr == 0)
return;
- if (PT_OP_VALID(pagetable, put_gpuaddr))
- pagetable->pt_ops->put_gpuaddr(pagetable, memdesc);
+ if (!kgsl_memdesc_is_global(memdesc))
+ unmap_fail = kgsl_mmu_unmap(pagetable, memdesc);
+
+ /*
+ * Do not free the gpuaddr/size if unmap fails. Because if we
+ * try to map this range in future, the iommu driver will throw
+ * a BUG_ON() because it feels we are overwriting a mapping.
+ */
+ if (PT_OP_VALID(pagetable, put_gpuaddr) && (unmap_fail == 0))
+ pagetable->pt_ops->put_gpuaddr(memdesc);
if (!kgsl_memdesc_is_global(memdesc))
memdesc->gpuaddr = 0;
+
+ memdesc->pagetable = NULL;
}
EXPORT_SYMBOL(kgsl_mmu_put_gpuaddr);
@@ -630,7 +642,12 @@ static int nommu_get_gpuaddr(struct kgsl_pagetable *pagetable,
memdesc->gpuaddr = (uint64_t) sg_phys(memdesc->sgt->sgl);
- return memdesc->gpuaddr != 0 ? 0 : -ENOMEM;
+ if (memdesc->gpuaddr) {
+ memdesc->pagetable = pagetable;
+ return 0;
+ }
+
+ return -ENOMEM;
}
static struct kgsl_mmu_pt_ops nommu_pt_ops = {
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index 3e32c25b3dbe..bc448d424ccb 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -92,7 +92,7 @@ struct kgsl_mmu_pt_ops {
u64 (*get_ttbr0)(struct kgsl_pagetable *);
u32 (*get_contextidr)(struct kgsl_pagetable *);
int (*get_gpuaddr)(struct kgsl_pagetable *, struct kgsl_memdesc *);
- void (*put_gpuaddr)(struct kgsl_pagetable *, struct kgsl_memdesc *);
+ void (*put_gpuaddr)(struct kgsl_memdesc *);
uint64_t (*find_svm_region)(struct kgsl_pagetable *, uint64_t, uint64_t,
uint64_t, uint64_t);
int (*set_svm_region)(struct kgsl_pagetable *, uint64_t, uint64_t);
@@ -181,8 +181,7 @@ int kgsl_mmu_map(struct kgsl_pagetable *pagetable,
struct kgsl_memdesc *memdesc);
int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable,
struct kgsl_memdesc *memdesc);
-void kgsl_mmu_put_gpuaddr(struct kgsl_pagetable *pagetable,
- struct kgsl_memdesc *memdesc);
+void kgsl_mmu_put_gpuaddr(struct kgsl_memdesc *memdesc);
unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr);
unsigned int kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu,
u64 ttbr0, uint64_t addr);
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index 72895c18119f..283b72c22db4 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -318,12 +318,11 @@ static int kgsl_cma_alloc_secure(struct kgsl_device *device,
static int kgsl_allocate_secure(struct kgsl_device *device,
struct kgsl_memdesc *memdesc,
- struct kgsl_pagetable *pagetable,
uint64_t size) {
int ret;
if (MMU_FEATURE(&device->mmu, KGSL_MMU_HYP_SECURE_ALLOC))
- ret = kgsl_sharedmem_page_alloc_user(memdesc, pagetable, size);
+ ret = kgsl_sharedmem_page_alloc_user(memdesc, size);
else
ret = kgsl_cma_alloc_secure(device, memdesc, size);
@@ -332,7 +331,6 @@ static int kgsl_allocate_secure(struct kgsl_device *device,
int kgsl_allocate_user(struct kgsl_device *device,
struct kgsl_memdesc *memdesc,
- struct kgsl_pagetable *pagetable,
uint64_t size, uint64_t flags)
{
int ret;
@@ -340,12 +338,11 @@ int kgsl_allocate_user(struct kgsl_device *device,
memdesc->flags = flags;
if (kgsl_mmu_get_mmutype(device) == KGSL_MMU_TYPE_NONE)
- ret = kgsl_sharedmem_alloc_contig(device, memdesc,
- pagetable, size);
+ ret = kgsl_sharedmem_alloc_contig(device, memdesc, size);
else if (flags & KGSL_MEMFLAGS_SECURE)
- ret = kgsl_allocate_secure(device, memdesc, pagetable, size);
+ ret = kgsl_allocate_secure(device, memdesc, size);
else
- ret = kgsl_sharedmem_page_alloc_user(memdesc, pagetable, size);
+ ret = kgsl_sharedmem_page_alloc_user(memdesc, size);
return ret;
}
@@ -574,12 +571,11 @@ int kgsl_cache_range_op(struct kgsl_memdesc *memdesc, uint64_t offset,
void *addr = (memdesc->hostptr) ?
memdesc->hostptr : (void *) memdesc->useraddr;
- /* Make sure that size is non-zero */
- if (!size)
+ if (size == 0 || size > UINT_MAX)
return -EINVAL;
- /* Make sure that the offset + size isn't bigger than we can handle */
- if ((offset + size) > ULONG_MAX)
+ /* Make sure that the offset + size does not overflow */
+ if ((offset + size < offset) || (offset + size < size))
return -ERANGE;
/* Make sure the offset + size do not overflow the address */
@@ -638,7 +634,6 @@ static inline int get_page_size(size_t size, unsigned int align)
int
kgsl_sharedmem_page_alloc_user(struct kgsl_memdesc *memdesc,
- struct kgsl_pagetable *pagetable,
uint64_t size)
{
int ret = 0;
@@ -672,7 +667,6 @@ kgsl_sharedmem_page_alloc_user(struct kgsl_memdesc *memdesc,
len_alloc = PAGE_ALIGN(size) >> PAGE_SHIFT;
- memdesc->pagetable = pagetable;
memdesc->ops = &kgsl_page_alloc_ops;
/*
@@ -806,18 +800,8 @@ void kgsl_sharedmem_free(struct kgsl_memdesc *memdesc)
if (memdesc == NULL || memdesc->size == 0)
return;
- if (memdesc->gpuaddr) {
- int ret = 0;
-
- ret = kgsl_mmu_unmap(memdesc->pagetable, memdesc);
- /*
- * Do not free the gpuaddr/size if unmap fails. Because if we
- * try to map this range in future, the iommu driver will throw
- * a BUG_ON() because it feels we are overwriting a mapping.
- */
- if (ret == 0)
- kgsl_mmu_put_gpuaddr(memdesc->pagetable, memdesc);
- }
+ /* Make sure the memory object has been unmapped */
+ kgsl_mmu_put_gpuaddr(memdesc);
if (memdesc->ops && memdesc->ops->free)
memdesc->ops->free(memdesc);
@@ -997,8 +981,7 @@ void kgsl_get_memory_usage(char *name, size_t name_size, uint64_t memflags)
EXPORT_SYMBOL(kgsl_get_memory_usage);
int kgsl_sharedmem_alloc_contig(struct kgsl_device *device,
- struct kgsl_memdesc *memdesc,
- struct kgsl_pagetable *pagetable, uint64_t size)
+ struct kgsl_memdesc *memdesc, uint64_t size)
{
int result = 0;
@@ -1007,7 +990,6 @@ int kgsl_sharedmem_alloc_contig(struct kgsl_device *device,
return -EINVAL;
memdesc->size = size;
- memdesc->pagetable = pagetable;
memdesc->ops = &kgsl_cma_ops;
memdesc->dev = device->dev->parent;
@@ -1098,7 +1080,6 @@ static int kgsl_cma_alloc_secure(struct kgsl_device *device,
{
struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);
int result = 0;
- struct kgsl_pagetable *pagetable = device->mmu.securepagetable;
size_t aligned;
/* Align size to 1M boundaries */
@@ -1118,7 +1099,6 @@ static int kgsl_cma_alloc_secure(struct kgsl_device *device,
memdesc->priv &= ~KGSL_MEMDESC_GUARD_PAGE;
memdesc->size = aligned;
- memdesc->pagetable = pagetable;
memdesc->ops = &kgsl_cma_ops;
memdesc->dev = iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE].dev;
diff --git a/drivers/gpu/msm/kgsl_sharedmem.h b/drivers/gpu/msm/kgsl_sharedmem.h
index 9e6817c76df8..03f278ead20f 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.h
+++ b/drivers/gpu/msm/kgsl_sharedmem.h
@@ -26,7 +26,7 @@ struct kgsl_process_private;
int kgsl_sharedmem_alloc_contig(struct kgsl_device *device,
struct kgsl_memdesc *memdesc,
- struct kgsl_pagetable *pagetable, uint64_t size);
+ uint64_t size);
void kgsl_sharedmem_free(struct kgsl_memdesc *memdesc);
@@ -66,13 +66,11 @@ void kgsl_sharedmem_uninit_sysfs(void);
int kgsl_allocate_user(struct kgsl_device *device,
struct kgsl_memdesc *memdesc,
- struct kgsl_pagetable *pagetable,
uint64_t size, uint64_t flags);
void kgsl_get_memory_usage(char *str, size_t len, uint64_t memflags);
int kgsl_sharedmem_page_alloc_user(struct kgsl_memdesc *memdesc,
- struct kgsl_pagetable *pagetable,
uint64_t size);
#define MEMFLAGS(_flags, _mask, _shift) \
@@ -287,11 +285,10 @@ static inline int kgsl_allocate_global(struct kgsl_device *device,
memdesc->priv = priv;
if ((memdesc->priv & KGSL_MEMDESC_CONTIG) != 0)
- ret = kgsl_sharedmem_alloc_contig(device, memdesc, NULL,
+ ret = kgsl_sharedmem_alloc_contig(device, memdesc,
(size_t) size);
else {
- ret = kgsl_sharedmem_page_alloc_user(memdesc, NULL,
- (size_t) size);
+ ret = kgsl_sharedmem_page_alloc_user(memdesc, (size_t) size);
if (ret == 0)
kgsl_memdesc_map(memdesc);
}
diff --git a/drivers/iio/adc/qcom-rradc.c b/drivers/iio/adc/qcom-rradc.c
index ebb49230d4d7..e08de7a808eb 100644
--- a/drivers/iio/adc/qcom-rradc.c
+++ b/drivers/iio/adc/qcom-rradc.c
@@ -165,7 +165,8 @@
#define FG_ADC_RR_CHG_THRESHOLD_SCALE 4
#define FG_ADC_RR_VOLT_INPUT_FACTOR 8
-#define FG_ADC_RR_CURR_INPUT_FACTOR 2
+#define FG_ADC_RR_CURR_INPUT_FACTOR 2000
+#define FG_ADC_RR_CURR_USBIN_INPUT_FACTOR_MIL 1886
#define FG_ADC_SCALE_MILLI_FACTOR 1000
#define FG_ADC_KELVINMIL_CELSIUSMIL 273150
@@ -323,12 +324,20 @@ static int rradc_post_process_curr(struct rradc_chip *chip,
struct rradc_chan_prop *prop, u16 adc_code,
int *result_ua)
{
- int64_t ua = 0;
+ int64_t ua = 0, scale = 0;
- /* 0.5 V/A; 2.5V ADC full scale */
- ua = ((int64_t)adc_code * FG_ADC_RR_CURR_INPUT_FACTOR);
+ if (!prop)
+ return -EINVAL;
+
+ if (prop->channel == RR_ADC_USBIN_I)
+ scale = FG_ADC_RR_CURR_USBIN_INPUT_FACTOR_MIL;
+ else
+ scale = FG_ADC_RR_CURR_INPUT_FACTOR;
+
+ /* scale * V/A; 2.5V ADC full scale */
+ ua = ((int64_t)adc_code * scale);
ua *= (FG_ADC_RR_FS_VOLTAGE_MV * FG_ADC_SCALE_MILLI_FACTOR);
- ua = div64_s64(ua, FG_MAX_ADC_READINGS);
+ ua = div64_s64(ua, (FG_MAX_ADC_READINGS * 1000));
*result_ua = ua;
return 0;
diff --git a/drivers/iio/adc/qcom-tadc.c b/drivers/iio/adc/qcom-tadc.c
index 3cc2694f9a03..4a56847a43e7 100644
--- a/drivers/iio/adc/qcom-tadc.c
+++ b/drivers/iio/adc/qcom-tadc.c
@@ -398,7 +398,7 @@ static int tadc_do_conversion(struct tadc_chip *chip, u8 channels, s16 *adc)
}
for (i = 0; i < TADC_NUM_CH; i++)
- adc[i] = val[i * 2] | val[i * 2 + 1] << BITS_PER_BYTE;
+ adc[i] = (s16)(val[i * 2] | (u16)val[i * 2 + 1] << 8);
return jiffies_to_msecs(timeout - timeleft);
}
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index fda10abae58a..eac6d07e6097 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -528,6 +528,8 @@ static bool arm_smmu_is_static_cb(struct arm_smmu_device *smmu);
static bool arm_smmu_is_slave_side_secure(struct arm_smmu_domain *smmu_domain);
static bool arm_smmu_has_secure_vmid(struct arm_smmu_domain *smmu_domain);
+static int arm_smmu_enable_s1_translations(struct arm_smmu_domain *smmu_domain);
+
static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
{
return container_of(dom, struct arm_smmu_domain, domain);
@@ -1604,7 +1606,8 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
/* SCTLR */
reg = SCTLR_CFCFG | SCTLR_CFIE | SCTLR_CFRE | SCTLR_EAE_SBOP;
- if (!(smmu_domain->attributes & (1 << DOMAIN_ATTR_S1_BYPASS)) ||
+ if ((!(smmu_domain->attributes & (1 << DOMAIN_ATTR_S1_BYPASS)) &&
+ !(smmu_domain->attributes & (1 << DOMAIN_ATTR_EARLY_MAP))) ||
!stage1)
reg |= SCTLR_M;
if (stage1)
@@ -1651,7 +1654,7 @@ static void arm_smmu_secure_domain_unlock(struct arm_smmu_domain *smmu_domain)
static unsigned long arm_smmu_pgtbl_lock(struct arm_smmu_domain *smmu_domain)
{
- unsigned long flags;
+ unsigned long flags = 0;
if (arm_smmu_is_slave_side_secure(smmu_domain))
mutex_lock(&smmu_domain->pgtbl_mutex_lock);
@@ -3043,6 +3046,11 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
ret = 0;
break;
}
+ case DOMAIN_ATTR_EARLY_MAP:
+ *((int *)data) = !!(smmu_domain->attributes
+ & (1 << DOMAIN_ATTR_EARLY_MAP));
+ ret = 0;
+ break;
default:
ret = -ENODEV;
break;
@@ -3148,6 +3156,24 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
smmu_domain->attributes |= 1 << DOMAIN_ATTR_FAST;
ret = 0;
break;
+ case DOMAIN_ATTR_EARLY_MAP: {
+ int early_map = *((int *)data);
+
+ ret = 0;
+ if (early_map) {
+ smmu_domain->attributes |=
+ 1 << DOMAIN_ATTR_EARLY_MAP;
+ } else {
+ if (smmu_domain->smmu)
+ ret = arm_smmu_enable_s1_translations(
+ smmu_domain);
+
+ if (!ret)
+ smmu_domain->attributes &=
+ ~(1 << DOMAIN_ATTR_EARLY_MAP);
+ }
+ break;
+ }
default:
ret = -ENODEV;
break;
@@ -3158,6 +3184,28 @@ out_unlock:
return ret;
}
+
+static int arm_smmu_enable_s1_translations(struct arm_smmu_domain *smmu_domain)
+{
+ struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
+ void __iomem *cb_base;
+ u32 reg;
+ int ret;
+
+ cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
+ ret = arm_smmu_enable_clocks(smmu);
+ if (ret)
+ return ret;
+
+ reg = readl_relaxed(cb_base + ARM_SMMU_CB_SCTLR);
+ reg |= SCTLR_M;
+
+ writel_relaxed(reg, cb_base + ARM_SMMU_CB_SCTLR);
+ arm_smmu_disable_clocks(smmu);
+ return ret;
+}
+
static int arm_smmu_dma_supported(struct iommu_domain *domain,
struct device *dev, u64 mask)
{
diff --git a/drivers/iommu/iommu-debug.c b/drivers/iommu/iommu-debug.c
index 3b54fd4a77e6..7b0c1ae5a48d 100644
--- a/drivers/iommu/iommu-debug.c
+++ b/drivers/iommu/iommu-debug.c
@@ -70,6 +70,8 @@ static const char *iommu_debug_attr_to_string(enum iommu_attr attr)
return "DOMAIN_ATTR_S1_BYPASS";
case DOMAIN_ATTR_FAST:
return "DOMAIN_ATTR_FAST";
+ case DOMAIN_ATTR_EARLY_MAP:
+ return "DOMAIN_ATTR_EARLY_MAP";
default:
return "Unknown attr!";
}
diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c
index 51fd79f101c8..674ca6161af9 100644
--- a/drivers/leds/leds-qpnp-flash-v2.c
+++ b/drivers/leds/leds-qpnp-flash-v2.c
@@ -10,6 +10,8 @@
* GNU General Public License for more details.
*/
+#define pr_fmt(fmt) "flashv2: %s: " fmt, __func__
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -27,6 +29,8 @@
#include <linux/regulator/consumer.h>
#include <linux/leds-qpnp-flash.h>
#include <linux/leds-qpnp-flash-v2.h>
+#include <linux/qpnp/qpnp-revid.h>
+#include <linux/log2.h>
#include "leds.h"
#define FLASH_LED_REG_LED_STATUS1(base) (base + 0x08)
@@ -43,24 +47,28 @@
#define FLASH_LED_REG_HDRM_AUTO_MODE_CTRL(base) (base + 0x50)
#define FLASH_LED_REG_WARMUP_DELAY(base) (base + 0x51)
#define FLASH_LED_REG_ISC_DELAY(base) (base + 0x52)
+#define FLASH_LED_REG_THERMAL_RMP_DN_RATE(base) (base + 0x55)
#define FLASH_LED_REG_THERMAL_THRSH1(base) (base + 0x56)
#define FLASH_LED_REG_THERMAL_THRSH2(base) (base + 0x57)
#define FLASH_LED_REG_THERMAL_THRSH3(base) (base + 0x58)
+#define FLASH_LED_REG_THERMAL_HYSTERESIS(base) (base + 0x59)
+#define FLASH_LED_REG_THERMAL_DEBOUNCE(base) (base + 0x5A)
#define FLASH_LED_REG_VPH_DROOP_THRESHOLD(base) (base + 0x61)
#define FLASH_LED_REG_VPH_DROOP_DEBOUNCE(base) (base + 0x62)
#define FLASH_LED_REG_ILED_GRT_THRSH(base) (base + 0x67)
+#define FLASH_LED_REG_LED1N2_ICLAMP_LOW(base) (base + 0x68)
+#define FLASH_LED_REG_LED1N2_ICLAMP_MID(base) (base + 0x69)
+#define FLASH_LED_REG_LED3_ICLAMP_LOW(base) (base + 0x6A)
+#define FLASH_LED_REG_LED3_ICLAMP_MID(base) (base + 0x6B)
#define FLASH_LED_REG_MITIGATION_SEL(base) (base + 0x6E)
#define FLASH_LED_REG_MITIGATION_SW(base) (base + 0x6F)
#define FLASH_LED_REG_LMH_LEVEL(base) (base + 0x70)
#define FLASH_LED_REG_CURRENT_DERATE_EN(base) (base + 0x76)
-#define FLASH_LED_HDRM_MODE_PRGM_MASK GENMASK(7, 0)
#define FLASH_LED_HDRM_VOL_MASK GENMASK(7, 4)
#define FLASH_LED_CURRENT_MASK GENMASK(6, 0)
#define FLASH_LED_ENABLE_MASK GENMASK(2, 0)
#define FLASH_HW_STROBE_MASK GENMASK(2, 0)
-#define FLASH_LED_SAFETY_TMR_MASK GENMASK(7, 0)
-#define FLASH_LED_INT_RT_STS_MASK GENMASK(7, 0)
#define FLASH_LED_ISC_WARMUP_DELAY_MASK GENMASK(1, 0)
#define FLASH_LED_CURRENT_DERATE_EN_MASK GENMASK(2, 0)
#define FLASH_LED_VPH_DROOP_DEBOUNCE_MASK GENMASK(1, 0)
@@ -70,13 +78,19 @@
#define FLASH_LED_LMH_LEVEL_MASK GENMASK(1, 0)
#define FLASH_LED_VPH_DROOP_HYSTERESIS_MASK GENMASK(5, 4)
#define FLASH_LED_VPH_DROOP_THRESHOLD_MASK GENMASK(2, 0)
+#define FLASH_LED_THERMAL_HYSTERESIS_MASK GENMASK(1, 0)
+#define FLASH_LED_THERMAL_DEBOUNCE_MASK GENMASK(1, 0)
#define FLASH_LED_THERMAL_THRSH_MASK GENMASK(2, 0)
-#define FLASH_LED_THERMAL_OTST_MASK GENMASK(2, 0)
#define FLASH_LED_MOD_CTRL_MASK BIT(7)
#define FLASH_LED_HW_SW_STROBE_SEL_BIT BIT(2)
#define FLASH_LED_VPH_DROOP_FAULT_MASK BIT(4)
#define FLASH_LED_LMH_MITIGATION_EN_MASK BIT(0)
#define FLASH_LED_CHGR_MITIGATION_EN_MASK BIT(4)
+#define THERMAL_OTST1_RAMP_CTRL_MASK BIT(7)
+#define THERMAL_OTST1_RAMP_CTRL_SHIFT 7
+#define THERMAL_DERATE_SLOW_SHIFT 4
+#define THERMAL_DERATE_SLOW_MASK GENMASK(6, 4)
+#define THERMAL_DERATE_FAST_MASK GENMASK(2, 0)
#define VPH_DROOP_DEBOUNCE_US_TO_VAL(val_us) (val_us / 8)
#define VPH_DROOP_HYST_MV_TO_VAL(val_mv) (val_mv / 25)
@@ -85,17 +99,24 @@
#define MITIGATION_THRSH_MA_TO_VAL(val_ma) (val_ma / 100)
#define CURRENT_MA_TO_REG_VAL(curr_ma, ires_ua) ((curr_ma * 1000) / ires_ua - 1)
#define SAFETY_TMR_TO_REG_VAL(duration_ms) ((duration_ms / 10) - 1)
+#define THERMAL_HYST_TEMP_TO_VAL(val, divisor) (val / divisor)
#define FLASH_LED_ISC_WARMUP_DELAY_SHIFT 6
#define FLASH_LED_WARMUP_DELAY_DEFAULT 2
#define FLASH_LED_ISC_DELAY_DEFAULT 3
#define FLASH_LED_VPH_DROOP_DEBOUNCE_DEFAULT 2
+#define FLASH_LED_VPH_DROOP_HYST_SHIFT 4
#define FLASH_LED_VPH_DROOP_HYST_DEFAULT 2
#define FLASH_LED_VPH_DROOP_THRESH_DEFAULT 5
-#define FLASH_LED_VPH_DROOP_DEBOUNCE_MAX 3
-#define FLASH_LED_VPH_DROOP_HYST_MAX 3
+#define FLASH_LED_DEBOUNCE_MAX 3
+#define FLASH_LED_HYSTERESIS_MAX 3
#define FLASH_LED_VPH_DROOP_THRESH_MAX 7
+#define THERMAL_DERATE_SLOW_MAX 314592
+#define THERMAL_DERATE_FAST_MAX 512
+#define THERMAL_DEBOUNCE_TIME_MAX 64
+#define THERMAL_DERATE_HYSTERESIS_MAX 3
#define FLASH_LED_THERMAL_THRSH_MIN 3
+#define FLASH_LED_THERMAL_THRSH_MAX 7
#define FLASH_LED_THERMAL_OTST_LEVELS 3
#define FLASH_LED_VLED_MAX_DEFAULT_UV 3500000
#define FLASH_LED_IBATT_OCP_THRESH_DEFAULT_UA 4500000
@@ -173,18 +194,12 @@ struct flash_node_data {
bool led_on;
};
-struct flash_regulator_data {
- struct regulator *vreg;
- const char *reg_name;
- u32 max_volt_uv;
-};
struct flash_switch_data {
struct platform_device *pdev;
+ struct regulator *vreg;
struct led_classdev cdev;
- struct flash_regulator_data *reg_data;
int led_mask;
- int num_regulators;
bool regulator_on;
bool enabled;
};
@@ -193,28 +208,41 @@ struct flash_switch_data {
* Flash LED configuration read from device tree
*/
struct flash_led_platform_data {
- int *thermal_derate_current;
- int all_ramp_up_done_irq;
- int all_ramp_down_done_irq;
- int led_fault_irq;
- int ibatt_ocp_threshold_ua;
- int vled_max_uv;
- int rpara_uohm;
- int lmh_rbatt_threshold_uohm;
- int lmh_ocv_threshold_uv;
- u8 isc_delay;
- u8 warmup_delay;
- u8 current_derate_en_cfg;
- u8 vph_droop_threshold;
- u8 vph_droop_hysteresis;
- u8 vph_droop_debounce;
- u8 lmh_mitigation_sel;
- u8 chgr_mitigation_sel;
- u8 lmh_level;
- u8 iled_thrsh_val;
- u8 hw_strobe_option;
- bool hdrm_auto_mode_en;
- bool thermal_derate_en;
+ struct pmic_revid_data *pmic_rev_id;
+ int *thermal_derate_current;
+ int all_ramp_up_done_irq;
+ int all_ramp_down_done_irq;
+ int led_fault_irq;
+ int ibatt_ocp_threshold_ua;
+ int vled_max_uv;
+ int rpara_uohm;
+ int lmh_rbatt_threshold_uohm;
+ int lmh_ocv_threshold_uv;
+ int thermal_derate_slow;
+ int thermal_derate_fast;
+ int thermal_hysteresis;
+ int thermal_debounce;
+ int thermal_thrsh1;
+ int thermal_thrsh2;
+ int thermal_thrsh3;
+ u32 led1n2_iclamp_low_ma;
+ u32 led1n2_iclamp_mid_ma;
+ u32 led3_iclamp_low_ma;
+ u32 led3_iclamp_mid_ma;
+ u8 isc_delay;
+ u8 warmup_delay;
+ u8 current_derate_en_cfg;
+ u8 vph_droop_threshold;
+ u8 vph_droop_hysteresis;
+ u8 vph_droop_debounce;
+ u8 lmh_mitigation_sel;
+ u8 chgr_mitigation_sel;
+ u8 lmh_level;
+ u8 iled_thrsh_val;
+ u8 hw_strobe_option;
+ bool hdrm_auto_mode_en;
+ bool thermal_derate_en;
+ bool otst_ramp_bkup_en;
};
/*
@@ -237,22 +265,54 @@ struct qpnp_flash_led {
bool trigger_chgr;
};
-static int
-qpnp_flash_led_read(struct qpnp_flash_led *led, u16 addr, u8 *data)
+static int thermal_derate_slow_table[] = {
+ 128, 256, 512, 1024, 2048, 4096, 8192, 314592,
+};
+
+static int thermal_derate_fast_table[] = {
+ 32, 64, 96, 128, 256, 384, 512,
+};
+
+static int otst1_threshold_table[] = {
+ 85, 79, 73, 67, 109, 103, 97, 91,
+};
+
+static int otst2_threshold_table[] = {
+ 110, 104, 98, 92, 134, 128, 122, 116,
+};
+
+static int otst3_threshold_table[] = {
+ 125, 119, 113, 107, 149, 143, 137, 131,
+};
+
+static int qpnp_flash_led_read(struct qpnp_flash_led *led, u16 addr, u8 *data)
{
int rc;
uint val;
rc = regmap_read(led->regmap, addr, &val);
- if (rc < 0)
- dev_err(&led->pdev->dev, "Unable to read from 0x%04X rc = %d\n",
- addr, rc);
- else
- dev_dbg(&led->pdev->dev, "Read 0x%02X from addr 0x%04X\n",
- val, addr);
+ if (rc < 0) {
+ pr_err("Unable to read from 0x%04X rc = %d\n", addr, rc);
+ return rc;
+ }
+ pr_debug("Read 0x%02X from addr 0x%04X\n", val, addr);
*data = (u8)val;
- return rc;
+ return 0;
+}
+
+static int qpnp_flash_led_write(struct qpnp_flash_led *led, u16 addr, u8 data)
+{
+ int rc;
+
+ rc = regmap_write(led->regmap, addr, data);
+ if (rc < 0) {
+ pr_err("Unable to write to 0x%04X rc = %d\n", addr, rc);
+ return rc;
+ }
+
+ pr_debug("Wrote 0x%02X to addr 0x%04X\n", data, addr);
+ return 0;
}
static int
@@ -277,11 +337,10 @@ qpnp_flash_led_masked_write(struct qpnp_flash_led *led, u16 addr, u8 mask,
rc = regmap_update_bits(led->regmap, addr, mask, val);
if (rc < 0)
- dev_err(&led->pdev->dev, "Unable to update bits from 0x%04X, rc = %d\n",
- addr, rc);
+ pr_err("Unable to update bits from 0x%04X, rc = %d\n", addr,
+ rc);
else
- dev_dbg(&led->pdev->dev, "Wrote 0x%02X to addr 0x%04X\n",
- val, addr);
+ pr_debug("Wrote 0x%02X to addr 0x%04X\n", val, addr);
return rc;
}
@@ -295,13 +354,12 @@ led_brightness qpnp_flash_led_brightness_get(struct led_classdev *led_cdev)
static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
{
int rc, i, addr_offset;
- u8 val = 0;
+ u8 val = 0, mask;
for (i = 0; i < led->num_fnodes; i++) {
addr_offset = led->fnode[i].id;
- rc = qpnp_flash_led_masked_write(led,
+ rc = qpnp_flash_led_write(led,
FLASH_LED_REG_HDRM_PRGM(led->base + addr_offset),
- FLASH_LED_HDRM_MODE_PRGM_MASK,
led->fnode[i].hdrm_val);
if (rc < 0)
return rc;
@@ -309,9 +367,9 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
val |= 0x1 << led->fnode[i].id;
}
- rc = qpnp_flash_led_masked_write(led,
+ rc = qpnp_flash_led_write(led,
FLASH_LED_REG_HDRM_AUTO_MODE_CTRL(led->base),
- FLASH_LED_HDRM_MODE_PRGM_MASK, val);
+ val);
if (rc < 0)
return rc;
@@ -336,6 +394,70 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
if (rc < 0)
return rc;
+ val = (led->pdata->otst_ramp_bkup_en << THERMAL_OTST1_RAMP_CTRL_SHIFT);
+ mask = THERMAL_OTST1_RAMP_CTRL_MASK;
+ if (led->pdata->thermal_derate_slow >= 0) {
+ val |= (led->pdata->thermal_derate_slow <<
+ THERMAL_DERATE_SLOW_SHIFT);
+ mask |= THERMAL_DERATE_SLOW_MASK;
+ }
+
+ if (led->pdata->thermal_derate_fast >= 0) {
+ val |= led->pdata->thermal_derate_fast;
+ mask |= THERMAL_DERATE_FAST_MASK;
+ }
+
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_THERMAL_RMP_DN_RATE(led->base),
+ mask, val);
+ if (rc < 0)
+ return rc;
+
+ if (led->pdata->thermal_debounce >= 0) {
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_THERMAL_DEBOUNCE(led->base),
+ FLASH_LED_THERMAL_DEBOUNCE_MASK,
+ led->pdata->thermal_debounce);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (led->pdata->thermal_hysteresis >= 0) {
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_THERMAL_HYSTERESIS(led->base),
+ FLASH_LED_THERMAL_HYSTERESIS_MASK,
+ led->pdata->thermal_hysteresis);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (led->pdata->thermal_thrsh1 >= 0) {
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_THERMAL_THRSH1(led->base),
+ FLASH_LED_THERMAL_THRSH_MASK,
+ led->pdata->thermal_thrsh1);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (led->pdata->thermal_thrsh2 >= 0) {
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_THERMAL_THRSH2(led->base),
+ FLASH_LED_THERMAL_THRSH_MASK,
+ led->pdata->thermal_thrsh2);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (led->pdata->thermal_thrsh3 >= 0) {
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_THERMAL_THRSH3(led->base),
+ FLASH_LED_THERMAL_THRSH_MASK,
+ led->pdata->thermal_thrsh3);
+ if (rc < 0)
+ return rc;
+ }
+
rc = qpnp_flash_led_masked_write(led,
FLASH_LED_REG_VPH_DROOP_DEBOUNCE(led->base),
FLASH_LED_VPH_DROOP_DEBOUNCE_MASK,
@@ -385,6 +507,46 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
if (rc < 0)
return rc;
+ if (led->pdata->led1n2_iclamp_low_ma) {
+ val = CURRENT_MA_TO_REG_VAL(led->pdata->led1n2_iclamp_low_ma,
+ led->fnode[0].ires_ua);
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_LED1N2_ICLAMP_LOW(led->base),
+ FLASH_LED_CURRENT_MASK, val);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (led->pdata->led1n2_iclamp_mid_ma) {
+ val = CURRENT_MA_TO_REG_VAL(led->pdata->led1n2_iclamp_mid_ma,
+ led->fnode[0].ires_ua);
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_LED1N2_ICLAMP_MID(led->base),
+ FLASH_LED_CURRENT_MASK, val);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (led->pdata->led3_iclamp_low_ma) {
+ val = CURRENT_MA_TO_REG_VAL(led->pdata->led3_iclamp_low_ma,
+ led->fnode[3].ires_ua);
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_LED3_ICLAMP_LOW(led->base),
+ FLASH_LED_CURRENT_MASK, val);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (led->pdata->led3_iclamp_mid_ma) {
+ val = CURRENT_MA_TO_REG_VAL(led->pdata->led3_iclamp_mid_ma,
+ led->fnode[3].ires_ua);
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_LED3_ICLAMP_MID(led->base),
+ FLASH_LED_CURRENT_MASK, val);
+ if (rc < 0)
+ return rc;
+ }
+
return 0;
}
@@ -414,8 +576,7 @@ static int qpnp_flash_led_hw_strobe_enable(struct flash_node_data *fnode,
on ? fnode->hw_strobe_state_active :
fnode->hw_strobe_state_suspend);
if (rc < 0) {
- dev_err(&fnode->pdev->dev,
- "failed to change hw strobe pin state\n");
+ pr_err("failed to change hw strobe pin state\n");
return rc;
}
}
@@ -426,34 +587,27 @@ static int qpnp_flash_led_hw_strobe_enable(struct flash_node_data *fnode,
static int qpnp_flash_led_regulator_enable(struct qpnp_flash_led *led,
struct flash_switch_data *snode, bool on)
{
- int i, rc = 0;
+ int rc = 0;
+
+ if (!snode || !snode->vreg)
+ return 0;
if (snode->regulator_on == on)
return 0;
- if (on == false) {
- i = snode->num_regulators;
- goto out;
- }
+ if (on)
+ rc = regulator_enable(snode->vreg);
+ else
+ rc = regulator_disable(snode->vreg);
- for (i = 0; i < snode->num_regulators; i++) {
- rc = regulator_enable(snode->reg_data[i].vreg);
- if (rc < 0) {
- dev_err(&led->pdev->dev,
- "regulator enable failed, rc=%d\n", rc);
- goto out;
- }
+ if (rc < 0) {
+ pr_err("regulator_%s failed, rc=%d\n",
+ on ? "enable" : "disable", rc);
+ return rc;
}
- snode->regulator_on = true;
-
- return rc;
-
-out:
- while (i--)
- regulator_disable(snode->reg_data[i].vreg);
- snode->regulator_on = false;
- return rc;
+ snode->regulator_on = on ? true : false;
+ return 0;
}
static int get_property_from_fg(struct qpnp_flash_led *led,
@@ -463,14 +617,13 @@ static int get_property_from_fg(struct qpnp_flash_led *led,
union power_supply_propval pval = {0, };
if (!led->bms_psy) {
- dev_err(&led->pdev->dev, "no bms psy found\n");
+ pr_err("no bms psy found\n");
return -EINVAL;
}
rc = power_supply_get_property(led->bms_psy, prop, &pval);
if (rc) {
- dev_err(&led->pdev->dev,
- "bms psy doesn't support reading prop %d rc = %d\n",
+ pr_err("bms psy doesn't support reading prop %d rc = %d\n",
prop, rc);
return rc;
}
@@ -532,8 +685,7 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led)
rc = get_property_from_fg(led, POWER_SUPPLY_PROP_RESISTANCE,
&rbatt_uohm);
if (rc < 0) {
- dev_err(&led->pdev->dev, "bms psy does not support resistance, rc=%d\n",
- rc);
+ pr_err("bms psy does not support resistance, rc=%d\n", rc);
return rc;
}
@@ -543,16 +695,14 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led)
rc = get_property_from_fg(led, POWER_SUPPLY_PROP_VOLTAGE_OCV, &ocv_uv);
if (rc < 0) {
- dev_err(&led->pdev->dev, "bms psy does not support OCV, rc=%d\n",
- rc);
+ pr_err("bms psy does not support OCV, rc=%d\n", rc);
return rc;
}
rc = get_property_from_fg(led, POWER_SUPPLY_PROP_CURRENT_NOW,
&ibat_now);
if (rc < 0) {
- dev_err(&led->pdev->dev, "bms psy does not support current, rc=%d\n",
- rc);
+ pr_err("bms psy does not support current, rc=%d\n", rc);
return rc;
}
@@ -571,8 +721,7 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led)
FLASH_LED_LMH_MITIGATION_EN_MASK,
FLASH_LED_LMH_MITIGATION_ENABLE);
if (rc < 0) {
- dev_err(&led->pdev->dev, "trigger lmh mitigation failed, rc=%d\n",
- rc);
+ pr_err("trigger lmh mitigation failed, rc=%d\n", rc);
return rc;
}
@@ -617,9 +766,8 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led)
* before collapsing the battery. (available power/ flash input voltage)
*/
avail_flash_ua = div64_s64(avail_flash_power_fw, vin_flash_uv * MCONV);
- dev_dbg(&led->pdev->dev, "avail_iflash=%lld, ocv=%d, ibat=%d, rbatt=%d, trigger_lmh=%d\n",
- avail_flash_ua, ocv_uv, ibat_now, rbatt_uohm,
- led->trigger_lmh);
+ pr_debug("avail_iflash=%lld, ocv=%d, ibat=%d, rbatt=%d, trigger_lmh=%d\n",
+ avail_flash_ua, ocv_uv, ibat_now, rbatt_uohm, led->trigger_lmh);
return min(FLASH_LED_MAX_TOTAL_CURRENT_MA,
(int)(div64_s64(avail_flash_ua, MCONV)));
}
@@ -761,8 +909,7 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode)
FLASH_LED_LMH_MITIGATION_EN_MASK,
FLASH_LED_LMH_MITIGATION_DISABLE);
if (rc < 0) {
- dev_err(&led->pdev->dev, "disable lmh mitigation failed, rc=%d\n",
- rc);
+ pr_err("disable lmh mitigation failed, rc=%d\n", rc);
return rc;
}
}
@@ -773,8 +920,7 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode)
FLASH_LED_CHGR_MITIGATION_EN_MASK,
FLASH_LED_CHGR_MITIGATION_DISABLE);
if (rc < 0) {
- dev_err(&led->pdev->dev, "disable chgr mitigation failed, rc=%d\n",
- rc);
+ pr_err("disable chgr mitigation failed, rc=%d\n", rc);
return rc;
}
}
@@ -806,8 +952,7 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode)
rc = pinctrl_select_state(led->fnode[i].pinctrl,
led->fnode[i].gpio_state_suspend);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "failed to disable GPIO, rc=%d\n", rc);
+ pr_err("failed to disable GPIO, rc=%d\n", rc);
return rc;
}
}
@@ -816,8 +961,7 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode)
rc = qpnp_flash_led_hw_strobe_enable(&led->fnode[i],
led->pdata->hw_strobe_option, false);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Unable to disable hw strobe, rc=%d\n",
+ pr_err("Unable to disable hw strobe, rc=%d\n",
rc);
return rc;
}
@@ -835,8 +979,8 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
u8 val, mask;
if (snode->enabled == on) {
- dev_warn(&led->pdev->dev, "Switch node is already %s!\n",
- on ? "enabled" : "disabled");
+ pr_debug("Switch node is already %s!\n",
+ on ? "enabled" : "disabled");
return 0;
}
@@ -886,9 +1030,9 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
if (rc < 0)
return rc;
- rc = qpnp_flash_led_masked_write(led,
+ rc = qpnp_flash_led_write(led,
FLASH_LED_REG_SAFETY_TMR(led->base + addr_offset),
- FLASH_LED_SAFETY_TMR_MASK, led->fnode[i].duration);
+ led->fnode[i].duration);
if (rc < 0)
return rc;
@@ -898,8 +1042,7 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
rc = pinctrl_select_state(led->fnode[i].pinctrl,
led->fnode[i].gpio_state_active);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "failed to enable GPIO\n");
+ pr_err("failed to enable GPIO rc=%d\n", rc);
return rc;
}
}
@@ -908,8 +1051,8 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
rc = qpnp_flash_led_hw_strobe_enable(&led->fnode[i],
led->pdata->hw_strobe_option, true);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Unable to enable hw strobe\n");
+ pr_err("Unable to enable hw strobe rc=%d\n",
+ rc);
return rc;
}
}
@@ -930,8 +1073,7 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
FLASH_LED_LMH_MITIGATION_EN_MASK,
FLASH_LED_LMH_MITIGATION_ENABLE);
if (rc < 0) {
- dev_err(&led->pdev->dev, "trigger lmh mitigation failed, rc=%d\n",
- rc);
+ pr_err("trigger lmh mitigation failed, rc=%d\n", rc);
return rc;
}
}
@@ -942,8 +1084,7 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
FLASH_LED_CHGR_MITIGATION_EN_MASK,
FLASH_LED_CHGR_MITIGATION_ENABLE);
if (rc < 0) {
- dev_err(&led->pdev->dev, "trigger chgr mitigation failed, rc=%d\n",
- rc);
+ pr_err("trigger chgr mitigation failed, rc=%d\n", rc);
return rc;
}
}
@@ -975,15 +1116,14 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options,
led = dev_get_drvdata(&snode->pdev->dev);
if (!(options & FLASH_LED_PREPARE_OPTIONS_MASK)) {
- dev_err(&led->pdev->dev, "Invalid options %d\n", options);
+ pr_err("Invalid options %d\n", options);
return -EINVAL;
}
if (options & ENABLE_REGULATOR) {
rc = qpnp_flash_led_regulator_enable(led, snode, true);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "enable regulator failed, rc=%d\n", rc);
+ pr_err("enable regulator failed, rc=%d\n", rc);
return rc;
}
}
@@ -991,8 +1131,7 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options,
if (options & DISABLE_REGULATOR) {
rc = qpnp_flash_led_regulator_enable(led, snode, false);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "disable regulator failed, rc=%d\n", rc);
+ pr_err("disable regulator failed, rc=%d\n", rc);
return rc;
}
}
@@ -1000,8 +1139,7 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options,
if (options & QUERY_MAX_CURRENT) {
rc = qpnp_flash_led_get_max_avail_current(led);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "query max current failed, rc=%d\n", rc);
+ pr_err("query max current failed, rc=%d\n", rc);
return rc;
}
*max_current = rc;
@@ -1041,8 +1179,7 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev,
if (snode) {
rc = qpnp_flash_led_switch_set(snode, value > 0);
if (rc < 0)
- dev_err(&led->pdev->dev,
- "Failed to set flash LED switch\n");
+ pr_err("Failed to set flash LED switch rc=%d\n", rc);
} else if (fnode) {
qpnp_flash_led_node_set(fnode, value);
}
@@ -1050,6 +1187,31 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev,
spin_unlock(&led->lock);
}
+/* sysfs show function for flash_max_current */
+static ssize_t qpnp_flash_led_max_current_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int rc;
+ struct flash_switch_data *snode;
+ struct qpnp_flash_led *led;
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+
+ snode = container_of(led_cdev, struct flash_switch_data, cdev);
+ led = dev_get_drvdata(&snode->pdev->dev);
+
+ rc = qpnp_flash_led_get_max_avail_current(led);
+ if (rc < 0)
+ pr_err("query max current failed, rc=%d\n", rc);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", rc);
+}
+
+/* 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),
+};
+
static int flash_led_psy_notifier_call(struct notifier_block *nb,
unsigned long ev, void *v)
{
@@ -1063,7 +1225,7 @@ static int flash_led_psy_notifier_call(struct notifier_block *nb,
if (!strcmp(psy->desc->name, "bms")) {
led->bms_psy = power_supply_get_by_name("bms");
if (!led->bms_psy)
- dev_err(&led->pdev->dev, "Failed to get bms power_supply\n");
+ pr_err("Failed to get bms power_supply\n");
else
power_supply_unreg_notifier(&led->nb);
}
@@ -1093,13 +1255,12 @@ static irqreturn_t qpnp_flash_led_irq_handler(int irq, void *_led)
int rc;
u8 irq_status, led_status1, led_status2;
- dev_dbg(&led->pdev->dev, "irq received, irq=%d\n", irq);
+ pr_debug("irq received, irq=%d\n", irq);
rc = qpnp_flash_led_read(led,
FLASH_LED_REG_INT_RT_STS(led->base), &irq_status);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Failed to read interrupt status reg, rc=%d\n",
- rc);
+ pr_err("Failed to read interrupt status reg, rc=%d\n", rc);
goto exit;
}
@@ -1118,29 +1279,27 @@ static irqreturn_t qpnp_flash_led_irq_handler(int irq, void *_led)
rc = qpnp_flash_led_read(led,
FLASH_LED_REG_LED_STATUS1(led->base), &led_status1);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Failed to read led_status1 reg, rc=%d\n",
- rc);
+ pr_err("Failed to read led_status1 reg, rc=%d\n", rc);
goto exit;
}
rc = qpnp_flash_led_read(led,
FLASH_LED_REG_LED_STATUS2(led->base), &led_status2);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Failed to read led_status2 reg, rc=%d\n",
- rc);
+ pr_err("Failed to read led_status2 reg, rc=%d\n", rc);
goto exit;
}
if (led_status1)
- dev_emerg(&led->pdev->dev, "led short/open fault detected! led_status1=%x\n",
- led_status1);
+ pr_emerg("led short/open fault detected! led_status1=%x\n",
+ led_status1);
if (led_status2 & FLASH_LED_VPH_DROOP_FAULT_MASK)
- dev_emerg(&led->pdev->dev, "led vph_droop fault detected!\n");
+ pr_emerg("led vph_droop fault detected!\n");
}
- dev_dbg(&led->pdev->dev, "irq handled, irq_type=%x, irq_status=%x\n",
- irq_type, irq_status);
+ pr_debug("irq handled, irq_type=%x, irq_status=%x\n", irq_type,
+ irq_status);
exit:
return IRQ_HANDLED;
@@ -1156,104 +1315,6 @@ int qpnp_flash_led_unregister_irq_notifier(struct notifier_block *nb)
return atomic_notifier_chain_unregister(&irq_notifier_list, nb);
}
-static int qpnp_flash_led_regulator_setup(struct qpnp_flash_led *led,
- struct flash_switch_data *snode, bool on)
-{
- int i, rc = 0;
-
- if (on == false) {
- i = snode->num_regulators;
- goto out;
- }
-
- for (i = 0; i < snode->num_regulators; i++) {
- snode->reg_data[i].vreg = regulator_get(snode->cdev.dev,
- snode->reg_data[i].reg_name);
- if (IS_ERR(snode->reg_data[i].vreg)) {
- rc = PTR_ERR(snode->reg_data[i].vreg);
- dev_err(&led->pdev->dev,
- "Failed to get regulator, rc=%d\n", rc);
- goto out;
- }
-
- if (regulator_count_voltages(snode->reg_data[i].vreg) > 0) {
- rc = regulator_set_voltage(snode->reg_data[i].vreg,
- snode->reg_data[i].max_volt_uv,
- snode->reg_data[i].max_volt_uv);
- if (rc < 0) {
- dev_err(&led->pdev->dev,
- "regulator set voltage failed, rc=%d\n",
- rc);
- regulator_put(snode->reg_data[i].vreg);
- goto out;
- }
- }
- }
-
- return rc;
-
-out:
- while (i--) {
- if (regulator_count_voltages(snode->reg_data[i].vreg) > 0)
- regulator_set_voltage(snode->reg_data[i].vreg, 0,
- snode->reg_data[i].max_volt_uv);
-
- regulator_put(snode->reg_data[i].vreg);
- }
-
- return rc;
-}
-
-static int qpnp_flash_led_regulator_parse_dt(struct qpnp_flash_led *led,
- struct flash_switch_data *snode,
- struct device_node *node) {
-
- int i = 0, rc = 0, num_regs = 0;
- struct device_node *temp = NULL;
- const char *temp_string;
- u32 val;
-
- while ((temp = of_get_next_available_child(node, temp))) {
- if (of_find_property(temp, "regulator-name", NULL))
- num_regs++;
- }
- snode->num_regulators = num_regs;
-
- if (snode->num_regulators == 0)
- return 0;
-
- snode->reg_data = devm_kcalloc(&led->pdev->dev, snode->num_regulators,
- sizeof(*snode->reg_data),
- GFP_KERNEL);
- if (!snode->reg_data)
- return -ENOMEM;
-
- for_each_available_child_of_node(node, temp) {
- rc = of_property_read_string(temp, "regulator-name",
- &temp_string);
- if (!rc)
- snode->reg_data[i].reg_name = temp_string;
- else {
- dev_err(&led->pdev->dev,
- "Unable to read regulator name, rc=%d\n", rc);
- return rc;
- }
-
- rc = of_property_read_u32(temp, "max-voltage-uv", &val);
- if (!rc) {
- snode->reg_data[i].max_volt_uv = val;
- } else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to read max voltage, rc=%d\n", rc);
- return rc;
- }
-
- i++;
- }
-
- return 0;
-}
-
static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
struct flash_node_data *fnode, struct device_node *node)
{
@@ -1268,7 +1329,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
rc = of_property_read_string(node, "qcom,led-name", &fnode->cdev.name);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Unable to read flash LED names\n");
+ pr_err("Unable to read flash LED names\n");
return rc;
}
@@ -1279,11 +1340,11 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
} else if (!strcmp(temp_string, "torch")) {
fnode->type = FLASH_LED_TYPE_TORCH;
} else {
- dev_err(&led->pdev->dev, "Wrong flash LED type\n");
+ pr_err("Wrong flash LED type\n");
return rc;
}
} else {
- dev_err(&led->pdev->dev, "Unable to read flash LED label\n");
+ pr_err("Unable to read flash LED label\n");
return rc;
}
@@ -1291,14 +1352,14 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
if (!rc) {
fnode->id = (u8)val;
} else {
- dev_err(&led->pdev->dev, "Unable to read flash LED ID\n");
+ pr_err("Unable to read flash LED ID\n");
return rc;
}
rc = of_property_read_string(node, "qcom,default-led-trigger",
&fnode->cdev.default_trigger);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Unable to read trigger name\n");
+ pr_err("Unable to read trigger name\n");
return rc;
}
@@ -1310,7 +1371,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
fnode->ires = FLASH_LED_IRES_BASE -
(val - FLASH_LED_IRES_MIN_UA) / FLASH_LED_IRES_DIVISOR;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to read current resolution\n");
+ pr_err("Unable to read current resolution rc=%d\n", rc);
return rc;
}
@@ -1321,8 +1382,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
fnode->max_current = val;
fnode->cdev.max_brightness = val;
} else {
- dev_err(&led->pdev->dev,
- "Unable to read max current, rc=%d\n", rc);
+ pr_err("Unable to read max current, rc=%d\n", rc);
return rc;
}
@@ -1330,8 +1390,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
if (!rc) {
if (val < FLASH_LED_MIN_CURRENT_MA ||
val > fnode->max_current)
- dev_warn(&led->pdev->dev,
- "Invalid operational current specified, capping it\n");
+ pr_warn("Invalid operational current specified, capping it\n");
if (val < FLASH_LED_MIN_CURRENT_MA)
val = FLASH_LED_MIN_CURRENT_MA;
if (val > fnode->max_current)
@@ -1339,8 +1398,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
fnode->current_ma = val;
fnode->cdev.brightness = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to read operational current, rc=%d\n", rc);
+ pr_err("Unable to read operational current, rc=%d\n", rc);
return rc;
}
@@ -1351,13 +1409,11 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
FLASH_LED_SAFETY_TMR_ENABLE);
} else if (rc == -EINVAL) {
if (fnode->type == FLASH_LED_TYPE_FLASH) {
- dev_err(&led->pdev->dev,
- "Timer duration is required for flash LED\n");
+ pr_err("Timer duration is required for flash LED\n");
return rc;
}
} else {
- dev_err(&led->pdev->dev,
- "Unable to read timer duration\n");
+ pr_err("Unable to read timer duration\n");
return rc;
}
@@ -1369,7 +1425,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
fnode->hdrm_val = (val << FLASH_LED_HDRM_VOL_SHIFT) &
FLASH_LED_HDRM_VOL_MASK;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to read headroom voltage\n");
+ pr_err("Unable to read headroom voltage\n");
return rc;
}
@@ -1380,8 +1436,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
} else if (rc == -EINVAL) {
fnode->hdrm_val |= FLASH_LED_HDRM_VOL_HI_LO_WIN_DEFAULT_MV;
} else {
- dev_err(&led->pdev->dev,
- "Unable to read hdrm hi-lo window voltage\n");
+ pr_err("Unable to read hdrm hi-lo window voltage\n");
return rc;
}
@@ -1399,8 +1454,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
fnode->hw_strobe_gpio = of_get_named_gpio(node,
"qcom,hw-strobe-gpio", 0);
if (fnode->hw_strobe_gpio < 0) {
- dev_err(&led->pdev->dev,
- "Invalid gpio specified\n");
+ pr_err("Invalid gpio specified\n");
return fnode->hw_strobe_gpio;
}
gpio_direction_output(fnode->hw_strobe_gpio, 0);
@@ -1410,8 +1464,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
pinctrl_lookup_state(fnode->pinctrl,
"strobe_enable");
if (IS_ERR_OR_NULL(fnode->hw_strobe_state_active)) {
- dev_err(&led->pdev->dev,
- "No active pin for hardware strobe, rc=%ld\n",
+ pr_err("No active pin for hardware strobe, rc=%ld\n",
PTR_ERR(fnode->hw_strobe_state_active));
fnode->hw_strobe_state_active = NULL;
}
@@ -1420,8 +1473,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
pinctrl_lookup_state(fnode->pinctrl,
"strobe_disable");
if (IS_ERR_OR_NULL(fnode->hw_strobe_state_suspend)) {
- dev_err(&led->pdev->dev,
- "No suspend pin for hardware strobe, rc=%ld\n",
+ pr_err("No suspend pin for hardware strobe, rc=%ld\n",
PTR_ERR(fnode->hw_strobe_state_suspend)
);
fnode->hw_strobe_state_suspend = NULL;
@@ -1431,8 +1483,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
rc = led_classdev_register(&led->pdev->dev, &fnode->cdev);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Unable to register led node %d\n",
- fnode->id);
+ pr_err("Unable to register led node %d\n", fnode->id);
return rc;
}
@@ -1440,14 +1491,13 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
fnode->pinctrl = devm_pinctrl_get(fnode->cdev.dev);
if (IS_ERR_OR_NULL(fnode->pinctrl)) {
- dev_warn(&led->pdev->dev, "No pinctrl defined\n");
+ pr_debug("No pinctrl defined\n");
fnode->pinctrl = NULL;
} else {
fnode->gpio_state_active =
pinctrl_lookup_state(fnode->pinctrl, "led_enable");
if (IS_ERR_OR_NULL(fnode->gpio_state_active)) {
- dev_err(&led->pdev->dev,
- "Cannot lookup LED active state\n");
+ pr_err("Cannot lookup LED active state\n");
devm_pinctrl_put(fnode->pinctrl);
fnode->pinctrl = NULL;
return PTR_ERR(fnode->gpio_state_active);
@@ -1456,8 +1506,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
fnode->gpio_state_suspend =
pinctrl_lookup_state(fnode->pinctrl, "led_disable");
if (IS_ERR_OR_NULL(fnode->gpio_state_suspend)) {
- dev_err(&led->pdev->dev,
- "Cannot lookup LED disable state\n");
+ pr_err("Cannot lookup LED disable state\n");
devm_pinctrl_put(fnode->pinctrl);
fnode->pinctrl = NULL;
return PTR_ERR(fnode->gpio_state_suspend);
@@ -1471,46 +1520,48 @@ static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led,
struct flash_switch_data *snode,
struct device_node *node)
{
- int rc = 0;
+ int rc = 0, num;
+ char reg_name[16], reg_sup_name[16];
rc = of_property_read_string(node, "qcom,led-name", &snode->cdev.name);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Failed to read switch node name, rc=%d\n", rc);
+ pr_err("Failed to read switch node name, rc=%d\n", rc);
return rc;
}
+ rc = sscanf(snode->cdev.name, "led:switch_%d", &num);
+ if (!rc) {
+ pr_err("No number for switch device?\n");
+ return -EINVAL;
+ }
+
rc = of_property_read_string(node, "qcom,default-led-trigger",
&snode->cdev.default_trigger);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Unable to read trigger name, rc=%d\n", rc);
+ pr_err("Unable to read trigger name, rc=%d\n", rc);
return rc;
}
rc = of_property_read_u32(node, "qcom,led-mask", &snode->led_mask);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Unable to read led mask rc=%d\n", rc);
+ pr_err("Unable to read led mask rc=%d\n", rc);
return rc;
}
if (snode->led_mask < 1 || snode->led_mask > 7) {
- dev_err(&led->pdev->dev, "Invalid value for led-mask\n");
+ pr_err("Invalid value for led-mask\n");
return -EINVAL;
}
- rc = qpnp_flash_led_regulator_parse_dt(led, snode, node);
- if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Unable to parse regulator data, rc=%d\n", rc);
- return rc;
- }
-
- if (snode->num_regulators) {
- rc = qpnp_flash_led_regulator_setup(led, snode, true);
- if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Unable to setup regulator, rc=%d\n", rc);
+ scnprintf(reg_name, sizeof(reg_name), "switch%d-supply", num);
+ if (of_find_property(led->pdev->dev.of_node, reg_name, NULL)) {
+ scnprintf(reg_sup_name, sizeof(reg_sup_name), "switch%d", num);
+ snode->vreg = devm_regulator_get(&led->pdev->dev, reg_sup_name);
+ if (IS_ERR_OR_NULL(snode->vreg)) {
+ rc = PTR_ERR(snode->vreg);
+ if (rc != -EPROBE_DEFER)
+ pr_err("Failed to get regulator, rc=%d\n", rc);
+ snode->vreg = NULL;
return rc;
}
}
@@ -1520,8 +1571,7 @@ static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led,
snode->cdev.brightness_get = qpnp_flash_led_brightness_get;
rc = led_classdev_register(&led->pdev->dev, &snode->cdev);
if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Unable to register led switch node\n");
+ pr_err("Unable to register led switch node\n");
return rc;
}
@@ -1529,13 +1579,53 @@ static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led,
return 0;
}
+static int get_code_from_table(int *table, int len, int value)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (value == table[i])
+ break;
+ }
+
+ if (i == len) {
+ pr_err("Couldn't find %d from table\n", value);
+ return -ENODATA;
+ }
+
+ return i;
+}
+
static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
struct device_node *node)
{
+ struct device_node *revid_node;
int rc;
u32 val;
bool short_circuit_det, open_circuit_det, vph_droop_det;
+ revid_node = of_parse_phandle(node, "qcom,pmic-revid", 0);
+ if (!revid_node) {
+ pr_err("Missing qcom,pmic-revid property - driver failed\n");
+ return -EINVAL;
+ }
+
+ led->pdata->pmic_rev_id = get_revid_data(revid_node);
+ if (IS_ERR_OR_NULL(led->pdata->pmic_rev_id)) {
+ pr_err("Unable to get pmic_revid rc=%ld\n",
+ PTR_ERR(led->pdata->pmic_rev_id));
+ /*
+ * the revid peripheral must be registered, any failure
+ * here only indicates that the rev-id module has not
+ * probed yet.
+ */
+ return -EPROBE_DEFER;
+ }
+
+ pr_debug("PMIC subtype %d Digital major %d\n",
+ led->pdata->pmic_rev_id->pmic_subtype,
+ led->pdata->pmic_rev_id->rev4);
+
led->pdata->hdrm_auto_mode_en = of_property_read_bool(node,
"qcom,hdrm-auto-mode");
@@ -1545,8 +1635,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
led->pdata->isc_delay =
val >> FLASH_LED_ISC_WARMUP_DELAY_SHIFT;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to read ISC delay, rc=%d\n", rc);
+ pr_err("Unable to read ISC delay, rc=%d\n", rc);
return rc;
}
@@ -1556,8 +1645,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
led->pdata->warmup_delay =
val >> FLASH_LED_ISC_WARMUP_DELAY_SHIFT;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to read WARMUP delay, rc=%d\n", rc);
+ pr_err("Unable to read WARMUP delay, rc=%d\n", rc);
return rc;
}
@@ -1584,26 +1672,128 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
led->pdata->thermal_derate_current,
FLASH_LED_THERMAL_OTST_LEVELS);
if (rc < 0) {
- dev_err(&led->pdev->dev, "Unable to read thermal current limits, rc=%d\n",
- rc);
+ pr_err("Unable to read thermal current limits, rc=%d\n",
+ rc);
return rc;
}
}
+ led->pdata->otst_ramp_bkup_en =
+ !of_property_read_bool(node, "qcom,otst-ramp-back-up-dis");
+
+ led->pdata->thermal_derate_slow = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,thermal-derate-slow", &val);
+ if (!rc) {
+ if (val < 0 || val > THERMAL_DERATE_SLOW_MAX) {
+ pr_err("Invalid thermal_derate_slow %d\n", val);
+ return -EINVAL;
+ }
+
+ led->pdata->thermal_derate_slow =
+ get_code_from_table(thermal_derate_slow_table,
+ ARRAY_SIZE(thermal_derate_slow_table), val);
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read thermal derate slow, rc=%d\n", rc);
+ return rc;
+ }
+
+ led->pdata->thermal_derate_fast = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,thermal-derate-fast", &val);
+ if (!rc) {
+ if (val < 0 || val > THERMAL_DERATE_FAST_MAX) {
+ pr_err("Invalid thermal_derate_fast %d\n", val);
+ return -EINVAL;
+ }
+
+ led->pdata->thermal_derate_fast =
+ get_code_from_table(thermal_derate_fast_table,
+ ARRAY_SIZE(thermal_derate_fast_table), val);
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read thermal derate fast, rc=%d\n", rc);
+ return rc;
+ }
+
+ led->pdata->thermal_debounce = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,thermal-debounce", &val);
+ if (!rc) {
+ if (val < 0 || val > THERMAL_DEBOUNCE_TIME_MAX) {
+ pr_err("Invalid thermal_debounce %d\n", val);
+ return -EINVAL;
+ }
+
+ if (val >= 0 && val < 16)
+ led->pdata->thermal_debounce = 0;
+ else
+ led->pdata->thermal_debounce = ilog2(val) - 3;
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read thermal debounce, rc=%d\n", rc);
+ return rc;
+ }
+
+ led->pdata->thermal_hysteresis = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,thermal-hysteresis", &val);
+ if (!rc) {
+ if (led->pdata->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE)
+ val = THERMAL_HYST_TEMP_TO_VAL(val, 20);
+ else
+ val = THERMAL_HYST_TEMP_TO_VAL(val, 15);
+
+ if (val < 0 || val > THERMAL_DERATE_HYSTERESIS_MAX) {
+ pr_err("Invalid thermal_derate_hysteresis %d\n", val);
+ return -EINVAL;
+ }
+
+ led->pdata->thermal_hysteresis = val;
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read thermal hysteresis, rc=%d\n", rc);
+ return rc;
+ }
+
+ led->pdata->thermal_thrsh1 = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,thermal-thrsh1", &val);
+ if (!rc) {
+ led->pdata->thermal_thrsh1 =
+ get_code_from_table(otst1_threshold_table,
+ ARRAY_SIZE(otst1_threshold_table), val);
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read thermal thrsh1, rc=%d\n", rc);
+ return rc;
+ }
+
+ led->pdata->thermal_thrsh2 = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,thermal-thrsh2", &val);
+ if (!rc) {
+ led->pdata->thermal_thrsh2 =
+ get_code_from_table(otst2_threshold_table,
+ ARRAY_SIZE(otst2_threshold_table), val);
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read thermal thrsh2, rc=%d\n", rc);
+ return rc;
+ }
+
+ led->pdata->thermal_thrsh3 = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,thermal-thrsh3", &val);
+ if (!rc) {
+ led->pdata->thermal_thrsh3 =
+ get_code_from_table(otst3_threshold_table,
+ ARRAY_SIZE(otst3_threshold_table), val);
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read thermal thrsh3, rc=%d\n", rc);
+ return rc;
+ }
+
led->pdata->vph_droop_debounce = FLASH_LED_VPH_DROOP_DEBOUNCE_DEFAULT;
rc = of_property_read_u32(node, "qcom,vph-droop-debounce-us", &val);
if (!rc) {
led->pdata->vph_droop_debounce =
VPH_DROOP_DEBOUNCE_US_TO_VAL(val);
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to read VPH droop debounce, rc=%d\n", rc);
+ pr_err("Unable to read VPH droop debounce, rc=%d\n", rc);
return rc;
}
- if (led->pdata->vph_droop_debounce > FLASH_LED_VPH_DROOP_DEBOUNCE_MAX) {
- dev_err(&led->pdev->dev,
- "Invalid VPH droop debounce specified");
+ if (led->pdata->vph_droop_debounce > FLASH_LED_DEBOUNCE_MAX) {
+ pr_err("Invalid VPH droop debounce specified\n");
return -EINVAL;
}
@@ -1613,14 +1803,12 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
led->pdata->vph_droop_threshold =
VPH_DROOP_THRESH_MV_TO_VAL(val);
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to read VPH droop threshold, rc=%d\n", rc);
+ pr_err("Unable to read VPH droop threshold, rc=%d\n", rc);
return rc;
}
if (led->pdata->vph_droop_threshold > FLASH_LED_VPH_DROOP_THRESH_MAX) {
- dev_err(&led->pdev->dev,
- "Invalid VPH droop threshold specified");
+ pr_err("Invalid VPH droop threshold specified\n");
return -EINVAL;
}
@@ -1631,23 +1819,54 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
led->pdata->vph_droop_hysteresis =
VPH_DROOP_HYST_MV_TO_VAL(val);
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to read VPH droop hysteresis, rc=%d\n", rc);
+ pr_err("Unable to read VPH droop hysteresis, rc=%d\n", rc);
return rc;
}
- if (led->pdata->vph_droop_hysteresis > FLASH_LED_VPH_DROOP_HYST_MAX) {
- dev_err(&led->pdev->dev,
- "Invalid VPH droop hysteresis specified");
+ if (led->pdata->vph_droop_hysteresis > FLASH_LED_HYSTERESIS_MAX) {
+ pr_err("Invalid VPH droop hysteresis specified\n");
return -EINVAL;
}
+ led->pdata->vph_droop_hysteresis <<= FLASH_LED_VPH_DROOP_HYST_SHIFT;
+
rc = of_property_read_u32(node, "qcom,hw-strobe-option", &val);
if (!rc) {
led->pdata->hw_strobe_option = (u8)val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to parse hw strobe option, rc=%d\n", rc);
+ pr_err("Unable to parse hw strobe option, rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = of_property_read_u32(node, "qcom,led1n2-iclamp-low-ma", &val);
+ if (!rc) {
+ led->pdata->led1n2_iclamp_low_ma = val;
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read led1n2_iclamp_low current, rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = of_property_read_u32(node, "qcom,led1n2-iclamp-mid-ma", &val);
+ if (!rc) {
+ led->pdata->led1n2_iclamp_mid_ma = val;
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read led1n2_iclamp_mid current, rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = of_property_read_u32(node, "qcom,led3-iclamp-low-ma", &val);
+ if (!rc) {
+ led->pdata->led3_iclamp_low_ma = val;
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read led3_iclamp_low current, rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = of_property_read_u32(node, "qcom,led3-iclamp-mid-ma", &val);
+ if (!rc) {
+ led->pdata->led3_iclamp_mid_ma = val;
+ } else if (rc != -EINVAL) {
+ pr_err("Unable to read led3_iclamp_mid current, rc=%d\n", rc);
return rc;
}
@@ -1656,8 +1875,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->vled_max_uv = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse vled_max voltage, rc=%d\n",
- rc);
+ pr_err("Unable to parse vled_max voltage, rc=%d\n", rc);
return rc;
}
@@ -1667,8 +1885,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->ibatt_ocp_threshold_ua = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse ibatt_ocp threshold, rc=%d\n",
- rc);
+ pr_err("Unable to parse ibatt_ocp threshold, rc=%d\n", rc);
return rc;
}
@@ -1677,8 +1894,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->rpara_uohm = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse rparasitic, rc=%d\n",
- rc);
+ pr_err("Unable to parse rparasitic, rc=%d\n", rc);
return rc;
}
@@ -1688,8 +1904,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->lmh_ocv_threshold_uv = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse lmh ocv threshold, rc=%d\n",
- rc);
+ pr_err("Unable to parse lmh ocv threshold, rc=%d\n", rc);
return rc;
}
@@ -1699,8 +1914,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->lmh_rbatt_threshold_uohm = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse lmh rbatt threshold, rc=%d\n",
- rc);
+ pr_err("Unable to parse lmh rbatt threshold, rc=%d\n", rc);
return rc;
}
@@ -1709,8 +1923,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->lmh_level = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse lmh_level, rc=%d\n",
- rc);
+ pr_err("Unable to parse lmh_level, rc=%d\n", rc);
return rc;
}
@@ -1719,13 +1932,12 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->lmh_mitigation_sel = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse lmh_mitigation_sel, rc=%d\n",
- rc);
+ pr_err("Unable to parse lmh_mitigation_sel, rc=%d\n", rc);
return rc;
}
if (led->pdata->lmh_mitigation_sel > FLASH_LED_MITIGATION_SEL_MAX) {
- dev_err(&led->pdev->dev, "Invalid lmh_mitigation_sel specified\n");
+ pr_err("Invalid lmh_mitigation_sel specified\n");
return -EINVAL;
}
@@ -1734,13 +1946,12 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->chgr_mitigation_sel = val;
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse chgr_mitigation_sel, rc=%d\n",
- rc);
+ pr_err("Unable to parse chgr_mitigation_sel, rc=%d\n", rc);
return rc;
}
if (led->pdata->chgr_mitigation_sel > FLASH_LED_MITIGATION_SEL_MAX) {
- dev_err(&led->pdev->dev, "Invalid chgr_mitigation_sel specified\n");
+ pr_err("Invalid chgr_mitigation_sel specified\n");
return -EINVAL;
}
@@ -1751,30 +1962,29 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
if (!rc) {
led->pdata->iled_thrsh_val = MITIGATION_THRSH_MA_TO_VAL(val);
} else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev, "Unable to parse iled_thrsh_val, rc=%d\n",
- rc);
+ pr_err("Unable to parse iled_thrsh_val, rc=%d\n", rc);
return rc;
}
if (led->pdata->iled_thrsh_val > FLASH_LED_MITIGATION_THRSH_MAX) {
- dev_err(&led->pdev->dev, "Invalid iled_thrsh_val specified\n");
+ pr_err("Invalid iled_thrsh_val specified\n");
return -EINVAL;
}
led->pdata->all_ramp_up_done_irq =
of_irq_get_byname(node, "all-ramp-up-done-irq");
if (led->pdata->all_ramp_up_done_irq < 0)
- dev_dbg(&led->pdev->dev, "all-ramp-up-done-irq not used\n");
+ pr_debug("all-ramp-up-done-irq not used\n");
led->pdata->all_ramp_down_done_irq =
of_irq_get_byname(node, "all-ramp-down-done-irq");
if (led->pdata->all_ramp_down_done_irq < 0)
- dev_dbg(&led->pdev->dev, "all-ramp-down-done-irq not used\n");
+ pr_debug("all-ramp-down-done-irq not used\n");
led->pdata->led_fault_irq =
of_irq_get_byname(node, "led-fault-irq");
if (led->pdata->led_fault_irq < 0)
- dev_dbg(&led->pdev->dev, "led-fault-irq not used\n");
+ pr_debug("led-fault-irq not used\n");
return 0;
}
@@ -1785,18 +1995,18 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
struct device_node *node, *temp;
const char *temp_string;
unsigned int base;
- int rc, i = 0;
+ int rc, i = 0, j = 0;
node = pdev->dev.of_node;
if (!node) {
- dev_info(&pdev->dev, "No flash LED nodes defined\n");
+ pr_err("No flash LED nodes defined\n");
return -ENODEV;
}
rc = of_property_read_u32(node, "reg", &base);
if (rc < 0) {
- dev_err(&pdev->dev, "Couldn't find reg in node %s, rc = %d\n",
- node->full_name, rc);
+ pr_err("Couldn't find reg in node %s, rc = %d\n",
+ node->full_name, rc);
return rc;
}
@@ -1807,7 +2017,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
led->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!led->regmap) {
- dev_err(&pdev->dev, "Couldn't get parent's regmap\n");
+ pr_err("Couldn't get parent's regmap\n");
return -EINVAL;
}
@@ -1820,16 +2030,14 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
rc = qpnp_flash_led_parse_common_dt(led, node);
if (rc < 0) {
- dev_err(&pdev->dev,
- "Failed to parse common flash LED device tree\n");
+ pr_err("Failed to parse common flash LED device tree\n");
return rc;
}
for_each_available_child_of_node(node, temp) {
rc = of_property_read_string(temp, "label", &temp_string);
if (rc < 0) {
- dev_err(&pdev->dev,
- "Failed to parse label, rc=%d\n", rc);
+ pr_err("Failed to parse label, rc=%d\n", rc);
return rc;
}
@@ -1839,14 +2047,13 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
!strcmp("torch", temp_string)) {
led->num_fnodes++;
} else {
- dev_err(&pdev->dev,
- "Invalid label for led node\n");
+ pr_err("Invalid label for led node\n");
return -EINVAL;
}
}
if (!led->num_fnodes) {
- dev_err(&pdev->dev, "No LED nodes defined\n");
+ pr_err("No LED nodes defined\n");
return -ECHILD;
}
@@ -1863,26 +2070,34 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
return -ENOMEM;
temp = NULL;
- for (i = 0; i < led->num_fnodes; i++) {
- temp = of_get_next_available_child(node, temp);
- rc = qpnp_flash_led_parse_each_led_dt(led,
- &led->fnode[i], temp);
+ i = 0;
+ j = 0;
+ for_each_available_child_of_node(node, temp) {
+ rc = of_property_read_string(temp, "label", &temp_string);
if (rc < 0) {
- dev_err(&pdev->dev,
- "Unable to parse flash node %d rc=%d\n", i, rc);
- goto error_led_register;
+ pr_err("Failed to parse label, rc=%d\n", rc);
+ return rc;
}
- }
- for (i = 0; i < led->num_snodes; i++) {
- temp = of_get_next_available_child(node, temp);
- rc = qpnp_flash_led_parse_and_register_switch(led,
- &led->snode[i], temp);
- if (rc < 0) {
- dev_err(&pdev->dev,
- "Unable to parse and register switch node, rc=%d\n",
- rc);
- goto error_switch_register;
+ if (!strcmp("flash", temp_string) ||
+ !strcmp("torch", temp_string)) {
+ rc = qpnp_flash_led_parse_each_led_dt(led,
+ &led->fnode[i++], temp);
+ if (rc < 0) {
+ pr_err("Unable to parse flash node %d rc=%d\n",
+ i, rc);
+ goto error_led_register;
+ }
+ }
+
+ if (!strcmp("switch", temp_string)) {
+ rc = qpnp_flash_led_parse_and_register_switch(led,
+ &led->snode[j++], temp);
+ if (rc < 0) {
+ pr_err("Unable to parse and register switch node, rc=%d\n",
+ rc);
+ goto error_switch_register;
+ }
}
}
@@ -1894,8 +2109,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
IRQF_ONESHOT,
"qpnp_flash_led_all_ramp_up_done_irq", led);
if (rc < 0) {
- dev_err(&pdev->dev,
- "Unable to request all_ramp_up_done(%d) IRQ(err:%d)\n",
+ pr_err("Unable to request all_ramp_up_done(%d) IRQ(err:%d)\n",
led->pdata->all_ramp_up_done_irq, rc);
goto error_switch_register;
}
@@ -1908,8 +2122,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
IRQF_ONESHOT,
"qpnp_flash_led_all_ramp_down_done_irq", led);
if (rc < 0) {
- dev_err(&pdev->dev,
- "Unable to request all_ramp_down_done(%d) IRQ(err:%d)\n",
+ pr_err("Unable to request all_ramp_down_done(%d) IRQ(err:%d)\n",
led->pdata->all_ramp_down_done_irq, rc);
goto error_switch_register;
}
@@ -1922,8 +2135,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
IRQF_ONESHOT,
"qpnp_flash_led_fault_irq", led);
if (rc < 0) {
- dev_err(&pdev->dev,
- "Unable to request led_fault(%d) IRQ(err:%d)\n",
+ pr_err("Unable to request led_fault(%d) IRQ(err:%d)\n",
led->pdata->led_fault_irq, rc);
goto error_switch_register;
}
@@ -1933,25 +2145,46 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
if (!led->bms_psy) {
rc = flash_led_psy_register_notifier(led);
if (rc < 0) {
- dev_err(&pdev->dev, "Couldn't register psy notifier, rc = %d\n",
- rc);
+ pr_err("Couldn't register psy notifier, rc = %d\n", rc);
goto error_switch_register;
}
}
rc = qpnp_flash_led_init_settings(led);
if (rc < 0) {
- dev_err(&pdev->dev,
- "Failed to initialize flash LED, rc=%d\n", rc);
+ pr_err("Failed to initialize flash LED, rc=%d\n", rc);
goto unreg_notifier;
}
+ for (i = 0; i < led->num_snodes; i++) {
+ for (j = 0; j < ARRAY_SIZE(qpnp_flash_led_attrs); j++) {
+ rc = sysfs_create_file(&led->snode[i].cdev.dev->kobj,
+ &qpnp_flash_led_attrs[j].attr);
+ if (rc < 0) {
+ pr_err("sysfs creation failed, rc=%d\n", rc);
+ goto sysfs_fail;
+ }
+ }
+ }
+
spin_lock_init(&led->lock);
dev_set_drvdata(&pdev->dev, led);
return 0;
+sysfs_fail:
+ for (--j; j >= 0; j--)
+ sysfs_remove_file(&led->snode[i].cdev.dev->kobj,
+ &qpnp_flash_led_attrs[j].attr);
+
+ for (--i; i >= 0; i--) {
+ for (j = 0; j < ARRAY_SIZE(qpnp_flash_led_attrs); j++)
+ sysfs_remove_file(&led->snode[i].cdev.dev->kobj,
+ &qpnp_flash_led_attrs[j].attr);
+ }
+
+ i = led->num_snodes;
unreg_notifier:
power_supply_unreg_notifier(&led->nb);
error_switch_register:
@@ -1968,20 +2201,21 @@ error_led_register:
static int qpnp_flash_led_remove(struct platform_device *pdev)
{
struct qpnp_flash_led *led = dev_get_drvdata(&pdev->dev);
- int i;
+ int i, j;
for (i = 0; i < led->num_snodes; i++) {
- if (led->snode[i].num_regulators) {
- if (led->snode[i].regulator_on)
- qpnp_flash_led_regulator_enable(led,
- &led->snode[i], false);
- qpnp_flash_led_regulator_setup(led,
+ for (j = 0; j < ARRAY_SIZE(qpnp_flash_led_attrs); j++)
+ sysfs_remove_file(&led->snode[i].cdev.dev->kobj,
+ &qpnp_flash_led_attrs[j].attr);
+
+ if (led->snode[i].regulator_on)
+ qpnp_flash_led_regulator_enable(led,
&led->snode[i], false);
- }
}
while (i > 0)
led_classdev_unregister(&led->snode[--i].cdev);
+
i = led->num_fnodes;
while (i > 0)
led_classdev_unregister(&led->fnode[--i].cdev);
diff --git a/drivers/leds/leds-qpnp-flash.c b/drivers/leds/leds-qpnp-flash.c
index 95b4c42a5adb..98dfa56add51 100644
--- a/drivers/leds/leds-qpnp-flash.c
+++ b/drivers/leds/leds-qpnp-flash.c
@@ -82,7 +82,6 @@
#define FLASH_LED_HDRM_SNS_ENABLE_MASK 0x81
#define FLASH_MASK_MODULE_CONTRL_MASK 0xE0
#define FLASH_FOLLOW_OTST2_RB_MASK 0x08
-#define FLASH_PREPARE_OPTIONS_MASK 0x08
#define FLASH_LED_TRIGGER_DEFAULT "none"
#define FLASH_LED_HEADROOM_DEFAULT_MV 500
@@ -1172,7 +1171,7 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options,
flash_node = container_of(led_cdev, struct flash_node_data, cdev);
led = dev_get_drvdata(&flash_node->pdev->dev);
- if (!(options & FLASH_PREPARE_OPTIONS_MASK)) {
+ if (!(options & FLASH_LED_PREPARE_OPTIONS_MASK)) {
dev_err(&led->pdev->dev, "Invalid options %d\n", options);
return -EINVAL;
}
diff --git a/drivers/leds/leds-qpnp-wled.c b/drivers/leds/leds-qpnp-wled.c
index 894c1d88b3ef..79c54edefdc5 100644
--- a/drivers/leds/leds-qpnp-wled.c
+++ b/drivers/leds/leds-qpnp-wled.c
@@ -50,6 +50,7 @@
#define QPNP_WLED_VLOOP_COMP_RES_REG(b) (b + 0x55)
#define QPNP_WLED_VLOOP_COMP_GM_REG(b) (b + 0x56)
#define QPNP_WLED_PSM_CTRL_REG(b) (b + 0x5B)
+#define QPNP_WLED_LCD_AUTO_PFM_REG(b) (b + 0x5C)
#define QPNP_WLED_SC_PRO_REG(b) (b + 0x5E)
#define QPNP_WLED_SWIRE_AVDD_REG(b) (b + 0x5F)
#define QPNP_WLED_CTRL_SPARE_REG(b) (b + 0xDF)
@@ -61,11 +62,7 @@
#define QPNP_WLED_EN_MASK 0x7F
#define QPNP_WLED_EN_SHIFT 7
#define QPNP_WLED_FDBK_OP_MASK 0xF8
-#define QPNP_WLED_VREF_MASK 0xF0
-#define QPNP_WLED_VREF_STEP_MV 25
-#define QPNP_WLED_VREF_MIN_MV 300
-#define QPNP_WLED_VREF_MAX_MV 675
-#define QPNP_WLED_DFLT_VREF_MV 350
+#define QPNP_WLED_VREF_MASK GENMASK(3, 0)
#define QPNP_WLED_VLOOP_COMP_RES_MASK 0xF0
#define QPNP_WLED_VLOOP_COMP_RES_OVERWRITE 0x80
@@ -73,17 +70,29 @@
#define QPNP_WLED_LOOP_COMP_RES_STEP_KOHM 20
#define QPNP_WLED_LOOP_COMP_RES_MIN_KOHM 20
#define QPNP_WLED_LOOP_COMP_RES_MAX_KOHM 320
-#define QPNP_WLED_VLOOP_COMP_GM_MASK 0xF0
+#define QPNP_WLED_VLOOP_COMP_GM_MASK GENMASK(3, 0)
#define QPNP_WLED_VLOOP_COMP_GM_OVERWRITE 0x80
-#define QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED 0x03
+#define QPNP_WLED_VLOOP_COMP_AUTO_GM_EN BIT(6)
+#define QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_MASK GENMASK(5, 4)
+#define QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_SHIFT 4
+#define QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED_PMI8994 0x03
+#define QPNP_WLED_LOOP_GM_DFLT_AMOLED_PMICOBALT 0x09
+#define QPNP_WLED_LOOP_GM_DFLT_WLED 0x09
#define QPNP_WLED_LOOP_EA_GM_MIN 0x0
#define QPNP_WLED_LOOP_EA_GM_MAX 0xF
+#define QPNP_WLED_LOOP_AUTO_GM_THRESH_MAX 3
+#define QPNP_WLED_LOOP_AUTO_GM_DFLT_THRESH 1
#define QPNP_WLED_VREF_PSM_MASK 0xF8
#define QPNP_WLED_VREF_PSM_STEP_MV 50
#define QPNP_WLED_VREF_PSM_MIN_MV 400
#define QPNP_WLED_VREF_PSM_MAX_MV 750
#define QPNP_WLED_VREF_PSM_DFLT_AMOLED_MV 450
#define QPNP_WLED_PSM_CTRL_OVERWRITE 0x80
+#define QPNP_WLED_LCD_AUTO_PFM_DFLT_THRESH 1
+#define QPNP_WLED_LCD_AUTO_PFM_THRESH_MAX 0xF
+#define QPNP_WLED_LCD_AUTO_PFM_EN_SHIFT 7
+#define QPNP_WLED_LCD_AUTO_PFM_EN_BIT BIT(7)
+#define QPNP_WLED_LCD_AUTO_PFM_THRESH_MASK GENMASK(3, 0)
#define QPNP_WLED_ILIM_MASK GENMASK(2, 0)
#define QPNP_WLED_ILIM_OVERWRITE BIT(7)
@@ -275,6 +284,20 @@ static int qpnp_wled_ilim_settings_pmicobalt[NUM_SUPPORTED_ILIM_THRESHOLDS] = {
105, 280, 450, 620, 970, 1150, 1300, 1500,
};
+struct wled_vref_setting {
+ u32 min_uv;
+ u32 max_uv;
+ u32 step_uv;
+ u32 default_uv;
+};
+
+static struct wled_vref_setting vref_setting_pmi8994 = {
+ 300000, 675000, 25000, 350000,
+};
+static struct wled_vref_setting vref_setting_pmicobalt = {
+ 60000, 397500, 22500, 127500,
+};
+
/**
* qpnp_wled - wed data structure
* @ cdev - led class device
@@ -294,7 +317,7 @@ static int qpnp_wled_ilim_settings_pmicobalt[NUM_SUPPORTED_ILIM_THRESHOLDS] = {
* @ mod_freq_khz - modulator frequency in KHZ
* @ hyb_thres - threshold for hybrid dimming
* @ sync_dly_us - sync delay in us
- * @ vref_mv - ref voltage in mv
+ * @ vref_uv - ref voltage in uv
* @ vref_psm_mv - ref psm voltage in mv
* @ loop_comp_res_kohm - control to select the compensation resistor
* @ loop_ea_gm - control to select the gm for the gm stage in control loop
@@ -309,6 +332,10 @@ static int qpnp_wled_ilim_settings_pmicobalt[NUM_SUPPORTED_ILIM_THRESHOLDS] = {
* @ cons_sync_write_delay_us - delay between two consecutive writes to SYNC
* @ strings - supported list of strings
* @ num_strings - number of strings
+ * @ loop_auto_gm_thresh - the clamping level for auto gm
+ * @ lcd_auto_pfm_thresh - the threshold for lcd auto pfm mode
+ * @ loop_auto_gm_en - select if auto gm is enabled
+ * @ lcd_auto_pfm_en - select if auto pfm is enabled in lcd mode
* @ avdd_mode_spmi - enable avdd programming via spmi
* @ en_9b_dim_res - enable or disable 9bit dimming
* @ en_phase_stag - enable or disable phase staggering
@@ -337,7 +364,7 @@ struct qpnp_wled {
u16 mod_freq_khz;
u16 hyb_thres;
u16 sync_dly_us;
- u16 vref_mv;
+ u32 vref_uv;
u16 vref_psm_mv;
u16 loop_comp_res_kohm;
u16 loop_ea_gm;
@@ -352,6 +379,10 @@ struct qpnp_wled {
u16 cons_sync_write_delay_us;
u8 strings[QPNP_WLED_MAX_STRINGS];
u8 num_strings;
+ u8 loop_auto_gm_thresh;
+ u8 lcd_auto_pfm_thresh;
+ bool loop_auto_gm_en;
+ bool lcd_auto_pfm_en;
bool avdd_mode_spmi;
bool en_9b_dim_res;
bool en_phase_stag;
@@ -977,24 +1008,6 @@ static int qpnp_wled_set_disp(struct qpnp_wled *wled, u16 base_addr)
if (rc)
return rc;
- /* Configure the LOOP COMP GM register for AMOLED */
- if (wled->loop_ea_gm < QPNP_WLED_LOOP_EA_GM_MIN)
- wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MIN;
- else if (wled->loop_ea_gm > QPNP_WLED_LOOP_EA_GM_MAX)
- wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MAX;
-
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_VLOOP_COMP_GM_REG(wled->ctrl_base));
- if (rc < 0)
- return rc;
-
- reg &= QPNP_WLED_VLOOP_COMP_GM_MASK;
- reg |= (wled->loop_ea_gm | QPNP_WLED_VLOOP_COMP_GM_OVERWRITE);
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_VLOOP_COMP_GM_REG(wled->ctrl_base));
- if (rc)
- return rc;
-
/* Configure the CTRL TEST4 register for AMOLED */
rc = qpnp_wled_read_reg(wled, &reg,
QPNP_WLED_TEST4_REG(wled->ctrl_base));
@@ -1074,6 +1087,45 @@ static bool is_avdd_trim_adjustment_required(struct qpnp_wled *wled)
return !(reg & QPNP_WLED_AVDD_SET_BIT);
}
+static int qpnp_wled_gm_config(struct qpnp_wled *wled)
+{
+ int rc;
+ u8 mask = 0, reg = 0;
+
+ /* Configure the LOOP COMP GM register */
+ if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE ||
+ wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) {
+ if (wled->loop_auto_gm_en)
+ reg |= QPNP_WLED_VLOOP_COMP_AUTO_GM_EN;
+
+ if (wled->loop_auto_gm_thresh >
+ QPNP_WLED_LOOP_AUTO_GM_THRESH_MAX)
+ wled->loop_auto_gm_thresh =
+ QPNP_WLED_LOOP_AUTO_GM_THRESH_MAX;
+
+ reg |= wled->loop_auto_gm_thresh <<
+ QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_SHIFT;
+ mask |= QPNP_WLED_VLOOP_COMP_AUTO_GM_EN |
+ QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_MASK;
+ }
+
+ if (wled->loop_ea_gm < QPNP_WLED_LOOP_EA_GM_MIN)
+ wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MIN;
+ else if (wled->loop_ea_gm > QPNP_WLED_LOOP_EA_GM_MAX)
+ wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MAX;
+
+ reg |= wled->loop_ea_gm | QPNP_WLED_VLOOP_COMP_GM_OVERWRITE;
+ mask |= QPNP_WLED_VLOOP_COMP_GM_MASK |
+ QPNP_WLED_VLOOP_COMP_GM_OVERWRITE;
+
+ rc = qpnp_wled_masked_write_reg(wled, mask, &reg,
+ QPNP_WLED_VLOOP_COMP_GM_REG(wled->ctrl_base));
+ if (rc)
+ pr_err("write VLOOP_COMP_GM_REG failed, rc=%d]\n", rc);
+
+ return rc;
+}
+
static int qpnp_wled_ovp_config(struct qpnp_wled *wled)
{
int rc, i, *ovp_table;
@@ -1248,6 +1300,35 @@ static int qpnp_wled_ilim_config(struct qpnp_wled *wled)
return rc;
}
+static int qpnp_wled_vref_config(struct qpnp_wled *wled)
+{
+
+ struct wled_vref_setting vref_setting;
+ int rc;
+ u8 reg = 0;
+
+ if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE ||
+ wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE)
+ vref_setting = vref_setting_pmicobalt;
+ else
+ vref_setting = vref_setting_pmi8994;
+
+ if (wled->vref_uv < vref_setting.min_uv)
+ wled->vref_uv = vref_setting.min_uv;
+ else if (wled->vref_uv > vref_setting.max_uv)
+ wled->vref_uv = vref_setting.max_uv;
+
+ reg |= DIV_ROUND_CLOSEST(wled->vref_uv - vref_setting.min_uv,
+ vref_setting.step_uv);
+
+ rc = qpnp_wled_masked_write_reg(wled, QPNP_WLED_VREF_MASK,
+ &reg, QPNP_WLED_VREF_REG(wled->ctrl_base));
+ if (rc)
+ pr_err("Write VREF_REG failed, rc=%d\n", rc);
+
+ return rc;
+}
+
/* Configure WLED registers */
static int qpnp_wled_config(struct qpnp_wled *wled)
{
@@ -1272,22 +1353,18 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
return rc;
/* Configure the VREF register */
- if (wled->vref_mv < QPNP_WLED_VREF_MIN_MV)
- wled->vref_mv = QPNP_WLED_VREF_MIN_MV;
- else if (wled->vref_mv > QPNP_WLED_VREF_MAX_MV)
- wled->vref_mv = QPNP_WLED_VREF_MAX_MV;
-
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_VREF_REG(wled->ctrl_base));
- if (rc < 0)
+ rc = qpnp_wled_vref_config(wled);
+ if (rc < 0) {
+ pr_err("Error in configuring wled vref, rc=%d\n", rc);
return rc;
- reg &= QPNP_WLED_VREF_MASK;
- temp = wled->vref_mv - QPNP_WLED_VREF_MIN_MV;
- reg |= (temp / QPNP_WLED_VREF_STEP_MV);
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_VREF_REG(wled->ctrl_base));
- if (rc)
+ }
+
+ /* Configure VLOOP_COMP_GM register */
+ rc = qpnp_wled_gm_config(wled);
+ if (rc < 0) {
+ pr_err("Error in configureing wled gm, rc=%d\n", rc);
return rc;
+ }
/* Configure the ILIM register */
rc = qpnp_wled_ilim_config(wled);
@@ -1296,6 +1373,24 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
return rc;
}
+ /* Configure auto PFM mode for LCD mode only */
+ if ((wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE ||
+ wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE)
+ && !wled->disp_type_amoled) {
+ reg = 0;
+ reg |= wled->lcd_auto_pfm_thresh;
+ reg |= wled->lcd_auto_pfm_en <<
+ QPNP_WLED_LCD_AUTO_PFM_EN_SHIFT;
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_LCD_AUTO_PFM_EN_BIT |
+ QPNP_WLED_LCD_AUTO_PFM_THRESH_MASK, &reg,
+ QPNP_WLED_LCD_AUTO_PFM_REG(wled->ctrl_base));
+ if (rc < 0) {
+ pr_err("Write LCD_AUTO_PFM failed, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
/* Configure the Soft start Ramp delay: for AMOLED - 0,for LCD - 2 */
reg = (wled->disp_type_amoled) ? 0 : 2;
rc = qpnp_wled_write_reg(wled, reg,
@@ -1661,16 +1756,6 @@ static int qpnp_wled_parse_dt(struct qpnp_wled *wled)
return rc;
}
- wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED;
- rc = of_property_read_u32(pdev->dev.of_node,
- "qcom,loop-ea-gm", &temp_val);
- if (!rc) {
- wled->loop_ea_gm = temp_val;
- } else if (rc != -EINVAL) {
- dev_err(&pdev->dev, "Unable to read loop-ea-gm\n");
- return rc;
- }
-
wled->avdd_mode_spmi = of_property_read_bool(pdev->dev.of_node,
"qcom,avdd-mode-spmi");
@@ -1685,6 +1770,67 @@ static int qpnp_wled_parse_dt(struct qpnp_wled *wled)
}
}
+ if (wled->disp_type_amoled) {
+ if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE ||
+ wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE)
+ wled->loop_ea_gm =
+ QPNP_WLED_LOOP_GM_DFLT_AMOLED_PMICOBALT;
+ else
+ wled->loop_ea_gm =
+ QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED_PMI8994;
+ } else {
+ wled->loop_ea_gm = QPNP_WLED_LOOP_GM_DFLT_WLED;
+ }
+
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "qcom,loop-ea-gm", &temp_val);
+ if (!rc) {
+ wled->loop_ea_gm = temp_val;
+ } else if (rc != -EINVAL) {
+ dev_err(&pdev->dev, "Unable to read loop-ea-gm\n");
+ return rc;
+ }
+
+ if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE ||
+ wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) {
+ wled->loop_auto_gm_en =
+ of_property_read_bool(pdev->dev.of_node,
+ "qcom,loop-auto-gm-en");
+ wled->loop_auto_gm_thresh = QPNP_WLED_LOOP_AUTO_GM_DFLT_THRESH;
+ rc = of_property_read_u8(pdev->dev.of_node,
+ "qcom,loop-auto-gm-thresh",
+ &wled->loop_auto_gm_thresh);
+ if (rc && rc != -EINVAL) {
+ dev_err(&pdev->dev,
+ "Unable to read loop-auto-gm-thresh\n");
+ return rc;
+ }
+ }
+
+ if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE ||
+ wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) {
+
+ if (wled->pmic_rev_id->rev4 == PMICOBALT_V2P0_REV4)
+ wled->lcd_auto_pfm_en = false;
+ else
+ wled->lcd_auto_pfm_en = true;
+
+ wled->lcd_auto_pfm_thresh = QPNP_WLED_LCD_AUTO_PFM_DFLT_THRESH;
+ rc = of_property_read_u8(pdev->dev.of_node,
+ "qcom,lcd-auto-pfm-thresh",
+ &wled->lcd_auto_pfm_thresh);
+ if (rc && rc != -EINVAL) {
+ dev_err(&pdev->dev,
+ "Unable to read lcd-auto-pfm-thresh\n");
+ return rc;
+ }
+
+ if (wled->lcd_auto_pfm_thresh >
+ QPNP_WLED_LCD_AUTO_PFM_THRESH_MAX)
+ wled->lcd_auto_pfm_thresh =
+ QPNP_WLED_LCD_AUTO_PFM_THRESH_MAX;
+ }
+
wled->sc_deb_cycles = QPNP_WLED_SC_DEB_CYCLES_DFLT;
rc = of_property_read_u32(pdev->dev.of_node,
"qcom,sc-deb-cycles", &temp_val);
@@ -1714,11 +1860,15 @@ static int qpnp_wled_parse_dt(struct qpnp_wled *wled)
return rc;
}
- wled->vref_mv = QPNP_WLED_DFLT_VREF_MV;
+ if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE ||
+ wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE)
+ wled->vref_uv = vref_setting_pmicobalt.default_uv;
+ else
+ wled->vref_uv = vref_setting_pmi8994.default_uv;
rc = of_property_read_u32(pdev->dev.of_node,
- "qcom,vref-mv", &temp_val);
+ "qcom,vref-uv", &temp_val);
if (!rc) {
- wled->vref_mv = temp_val;
+ wled->vref_uv = temp_val;
} else if (rc != -EINVAL) {
dev_err(&pdev->dev, "Unable to read vref\n");
return rc;
diff --git a/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c b/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c
index 033ff7bcfca5..6c09f3820dfd 100644
--- a/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c
+++ b/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c
@@ -460,7 +460,7 @@ int msm_camera_set_clk_flags(struct clk *clk, unsigned long flags)
if (!clk)
return -EINVAL;
- CDBG("clk : %p, flags : %ld\n", clk, flags);
+ CDBG("clk : %pK, flags : %ld\n", clk, flags);
return clk_set_flags(clk, flags);
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index 1529e2aa740c..96f9e61578f2 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -1027,7 +1027,7 @@ static int msm_vfe40_start_fetch_engine(struct vfe_device *vfe_dev,
rc = vfe_dev->buf_mgr->ops->get_buf_by_index(
vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf);
if (rc < 0 || !buf) {
- pr_err("%s: No fetch buffer rc= %d buf= %p\n",
+ pr_err("%s: No fetch buffer rc= %d buf= %pK\n",
__func__, rc, buf);
return -EINVAL;
}
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 fdc98436a105..e8289f05d28f 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
@@ -67,7 +67,7 @@ static int msm_isp_axi_create_stream(struct vfe_device *vfe_dev,
} else {
/* check if the stream has been added for the vfe-device */
if (stream_info->vfe_mask & (1 << vfe_dev->pdev->id)) {
- pr_err("%s: stream %p/%x is already added for vfe dev %d vfe_mask %x\n",
+ pr_err("%s: stream %pK/%x is already added for vfe dev %d vfe_mask %x\n",
__func__, stream_info, stream_info->stream_id,
vfe_dev->pdev->id, stream_info->vfe_mask);
return -EINVAL;
@@ -1255,7 +1255,7 @@ int msm_isp_release_axi_stream(struct vfe_device *vfe_dev, void *arg)
if (vfe_idx == -ENOTTY ||
stream_release_cmd->stream_handle !=
stream_info->stream_handle[vfe_idx]) {
- pr_err("%s: Invalid stream %p handle %x/%x vfe_idx %d vfe_dev %d num_isp %d\n",
+ pr_err("%s: Invalid stream %pK handle %x/%x vfe_idx %d vfe_dev %d num_isp %d\n",
__func__, stream_info,
stream_release_cmd->stream_handle,
vfe_idx != -ENOTTY ?
@@ -3483,7 +3483,7 @@ static int msm_isp_stream_axi_cfg_update(struct vfe_device *vfe_dev,
if (stream_info->update_vfe_mask) {
if (stream_info->update_vfe_mask & (1 << vfe_dev->pdev->id)) {
spin_unlock_irqrestore(&stream_info->lock, flags);
- pr_err("%s: Stream %p/%x Update already in progress for vfe %d\n",
+ pr_err("%s: Stream %pK/%x Update already in progress for vfe %d\n",
__func__, stream_info, stream_info->stream_src,
vfe_dev->pdev->id);
return -EINVAL;
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
index df95e5cb9b99..094a7861831a 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -840,7 +840,7 @@ static uint16_t msm_ispif_get_cids_mask_from_cfg(
uint16_t cids_mask = 0;
BUG_ON(!entry);
- for (i = 0; i < entry->num_cids; i++)
+ for (i = 0; i < entry->num_cids && i < MAX_CID_CH_PARAM_ENTRY; i++)
cids_mask |= (1 << entry->cids[i]);
return cids_mask;
@@ -970,7 +970,7 @@ static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint32_t cmd_bits,
pr_err("%s: invalid interface type\n", __func__);
return;
}
- if (params->entries[i].num_cids > MAX_CID_CH) {
+ if (params->entries[i].num_cids > MAX_CID_CH_PARAM_ENTRY) {
pr_err("%s: out of range of cid_num %d\n",
__func__, params->entries[i].num_cids);
return;
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
index 59135225cb15..c779ee46c19a 100644
--- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
@@ -286,7 +286,7 @@ static int msm_vb2_put_buf(struct vb2_v4l2_buffer *vb, int session_id,
break;
}
if (vb2_v4l2_buf != vb) {
- pr_err("VB buffer is INVALID vb=%p, ses_id=%d, str_id=%d\n",
+ pr_err("VB buffer is INVALID vb=%pK, ses_id=%d, str_id=%d\n",
vb, session_id, stream_id);
spin_unlock_irqrestore(&stream->stream_lock, flags);
return -EINVAL;
@@ -329,7 +329,7 @@ static int msm_vb2_buf_done(struct vb2_v4l2_buffer *vb, int session_id,
break;
}
if (vb2_v4l2_buf != vb) {
- pr_err("VB buffer is INVALID ses_id=%d, str_id=%d, vb=%p\n",
+ pr_err("VB buffer is INVALID ses_id=%d, str_id=%d, vb=%pK\n",
session_id, stream_id, vb);
spin_unlock_irqrestore(&stream->stream_lock, flags);
return -EINVAL;
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c
index 2c313016bc90..8213f736205a 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c
@@ -66,39 +66,72 @@ int msm_cpp_get_clock_index(struct cpp_device *cpp_dev, const char *clk_name)
return -EINVAL;
}
-static int cpp_get_clk_freq_tbl(struct clk *clk, struct cpp_hw_info *hw_info,
- uint32_t min_clk_rate)
+static int cpp_get_clk_freq_tbl_dt(struct cpp_device *cpp_dev)
{
- uint32_t i;
+ uint32_t i, count, min_clk_rate;
uint32_t idx = 0;
- signed long freq_tbl_entry = 0;
+ struct device_node *of_node;
+ uint32_t *rates;
+ int32_t rc = 0;
+ struct cpp_hw_info *hw_info;
- if ((clk == NULL) || (hw_info == NULL) || (clk->ops == NULL) ||
- (clk->ops->list_rate == NULL)) {
+ if (cpp_dev == NULL) {
pr_err("Bad parameter\n");
- return -EINVAL;
+ rc = -EINVAL;
+ goto err;
}
- for (i = 0; i < MAX_FREQ_TBL; i++) {
- freq_tbl_entry = clk->ops->list_rate(clk, i);
- pr_debug("entry=%ld\n", freq_tbl_entry);
- if (freq_tbl_entry >= 0) {
- if (freq_tbl_entry >= min_clk_rate) {
- hw_info->freq_tbl[idx++] = freq_tbl_entry;
- pr_debug("tbl[%d]=%ld\n", idx-1,
- freq_tbl_entry);
+ of_node = cpp_dev->pdev->dev.of_node;
+ min_clk_rate = cpp_dev->min_clk_rate;
+ hw_info = &cpp_dev->hw_info;
+
+ if ((hw_info == NULL) || (of_node == NULL)) {
+ pr_err("Invalid hw_info %p or ofnode %p\n", hw_info, of_node);
+ rc = -EINVAL;
+ goto err;
+
+ }
+ count = of_property_count_u32_elems(of_node, "qcom,src-clock-rates");
+ if ((count == 0) || (count > MAX_FREQ_TBL)) {
+ pr_err("Clock count is invalid\n");
+ rc = -EINVAL;
+ goto err;
+ }
+
+ rates = devm_kcalloc(&cpp_dev->pdev->dev, count, sizeof(uint32_t),
+ GFP_KERNEL);
+ if (!rates) {
+ rc = -ENOMEM;
+ goto err;
+ }
+
+ rc = of_property_read_u32_array(of_node, "qcom,src-clock-rates",
+ rates, count);
+ if (rc) {
+ rc = -EINVAL;
+ goto mem_free;
+ }
+
+ for (i = 0; i < count; i++) {
+ pr_debug("entry=%d\n", rates[i]);
+ if (rates[i] >= 0) {
+ if (rates[i] >= min_clk_rate) {
+ hw_info->freq_tbl[idx++] = rates[i];
+ pr_debug("tbl[%d]=%d\n", idx-1, rates[i]);
}
} else {
- pr_debug("freq table returned invalid entry/end %ld\n",
- freq_tbl_entry);
+ pr_debug("rate is invalid entry/end %d\n", rates[i]);
break;
}
}
- pr_debug("%s: idx %d", __func__, idx);
+ pr_debug("%s: idx %d\n", __func__, idx);
hw_info->freq_tbl_count = idx;
- return 0;
+mem_free:
+ devm_kfree(&cpp_dev->pdev->dev, rates);
+err:
+ return rc;
}
int msm_cpp_set_micro_clk(struct cpp_device *cpp_dev)
@@ -147,8 +180,7 @@ int msm_update_freq_tbl(struct cpp_device *cpp_dev)
rc = msm_cpp_core_clk_idx;
return rc;
}
- rc = cpp_get_clk_freq_tbl(cpp_dev->cpp_clk[msm_cpp_core_clk_idx],
- &cpp_dev->hw_info, cpp_dev->min_clk_rate);
+ rc = cpp_get_clk_freq_tbl_dt(cpp_dev);
if (rc < 0) {
pr_err("%s: fail to get frequency table\n", __func__);
return rc;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c
index 5f749bd46273..0d27de5c9b4b 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c
@@ -645,7 +645,7 @@ static int32_t msm_flash_release(
static int32_t msm_flash_config(struct msm_flash_ctrl_t *flash_ctrl,
void __user *argp)
{
- int32_t rc = -EINVAL;
+ int32_t rc = 0;
struct msm_flash_cfg_data_t *flash_data =
(struct msm_flash_cfg_data_t *) argp;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_tz_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_tz_i2c.c
index 25c152be2b71..5a330db0f9a5 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_tz_i2c.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_tz_i2c.c
@@ -794,7 +794,7 @@ int32_t msm_camera_tz_i2c_register_sensor(
return -EINVAL;
}
- CDBG("id=%d, client=%p\n", s_ctrl->id, s_ctrl);
+ CDBG("id=%d, client=%pK\n", s_ctrl->id, s_ctrl);
sensor_info[s_ctrl->id].s_ctrl = s_ctrl;
sensor_info[s_ctrl->id].secure = s_ctrl->is_secure;
return 0;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_debug.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_debug.c
index 94223b557990..cf33bc6437cc 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_debug.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_debug.c
@@ -49,6 +49,10 @@
#define SDE_ROT_EVTLOG_BUF_ALIGN 32
#define SDE_ROT_DEBUG_BASE_MAX 10
+#define SDE_ROT_DEFAULT_BASE_REG_CNT 0x100
+#define GROUP_BYTES 4
+#define ROW_BYTES 16
+
static DEFINE_SPINLOCK(sde_rot_xlock);
/*
@@ -963,6 +967,273 @@ static const struct file_operations sde_rotator_raw_ops = {
.release = single_release
};
+static int sde_rotator_debug_base_open(struct inode *inode, struct file *file)
+{
+ /* non-seekable */
+ file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+static int sde_rotator_debug_base_release(struct inode *inode,
+ struct file *file)
+{
+ struct sde_rotator_debug_base *dbg = file->private_data;
+
+ if (dbg && dbg->buf) {
+ kfree(dbg->buf);
+ dbg->buf_len = 0;
+ dbg->buf = NULL;
+ }
+ return 0;
+}
+
+static ssize_t sde_rotator_debug_base_offset_write(struct file *file,
+ const char __user *user_buf, size_t count, loff_t *ppos)
+{
+ struct sde_rotator_debug_base *dbg = file->private_data;
+ u32 off = 0;
+ u32 cnt = SDE_ROT_DEFAULT_BASE_REG_CNT;
+ char buf[24];
+
+ if (!dbg)
+ return -ENODEV;
+
+ if (count >= sizeof(buf))
+ return -EFAULT;
+
+ if (copy_from_user(buf, user_buf, count))
+ return -EFAULT;
+
+ buf[count] = 0;
+
+ if (sscanf(buf, "%5x %x", &off, &cnt) < 2)
+ return -EINVAL;
+
+ if (off > dbg->max_offset)
+ return -EINVAL;
+
+ if (cnt > (dbg->max_offset - off))
+ cnt = dbg->max_offset - off;
+
+ dbg->off = off;
+ dbg->cnt = cnt;
+
+ SDEROT_DBG("offset=%x cnt=%x\n", off, cnt);
+
+ return count;
+}
+
+static ssize_t sde_rotator_debug_base_offset_read(struct file *file,
+ char __user *buff, size_t count, loff_t *ppos)
+{
+ struct sde_rotator_debug_base *dbg = file->private_data;
+ int len = 0;
+ char buf[24] = {'\0'};
+
+ if (!dbg)
+ return -ENODEV;
+
+ if (*ppos)
+ return 0; /* the end */
+
+ len = snprintf(buf, sizeof(buf), "0x%08zx %zx\n", dbg->off, dbg->cnt);
+ if (len < 0 || len >= sizeof(buf))
+ return 0;
+
+ if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
+ return -EFAULT;
+
+ *ppos += len; /* increase offset */
+
+ return len;
+}
+
+static ssize_t sde_rotator_debug_base_reg_write(struct file *file,
+ const char __user *user_buf, size_t count, loff_t *ppos)
+{
+ struct sde_rotator_debug_base *dbg = file->private_data;
+ size_t off;
+ u32 data, cnt;
+ char buf[24];
+
+ if (!dbg)
+ return -ENODEV;
+
+ if (count >= sizeof(buf))
+ return -EFAULT;
+
+ if (copy_from_user(buf, user_buf, count))
+ return -EFAULT;
+
+ buf[count] = 0;
+
+ cnt = sscanf(buf, "%zx %x", &off, &data);
+
+ if (cnt < 2)
+ return -EFAULT;
+
+ if (off >= dbg->max_offset)
+ return -EFAULT;
+
+ /* Enable Clock for register access */
+ sde_rotator_clk_ctrl(dbg->mgr, true);
+
+ writel_relaxed(data, dbg->base + off);
+
+ /* Disable Clock after register access */
+ sde_rotator_clk_ctrl(dbg->mgr, false);
+
+ SDEROT_DBG("addr=%zx data=%x\n", off, data);
+
+ return count;
+}
+
+static ssize_t sde_rotator_debug_base_reg_read(struct file *file,
+ char __user *user_buf, size_t count, loff_t *ppos)
+{
+ struct sde_rotator_debug_base *dbg = file->private_data;
+ size_t len;
+
+ if (!dbg) {
+ SDEROT_ERR("invalid handle\n");
+ return -ENODEV;
+ }
+
+ if (!dbg->buf) {
+ char dump_buf[64];
+ char *ptr;
+ int cnt, tot;
+
+ dbg->buf_len = sizeof(dump_buf) *
+ DIV_ROUND_UP(dbg->cnt, ROW_BYTES);
+ dbg->buf = kzalloc(dbg->buf_len, GFP_KERNEL);
+
+ if (!dbg->buf) {
+ SDEROT_ERR("not enough memory to hold reg dump\n");
+ return -ENOMEM;
+ }
+
+ ptr = dbg->base + dbg->off;
+ tot = 0;
+
+ /* Enable clock for register access */
+ sde_rotator_clk_ctrl(dbg->mgr, true);
+
+ for (cnt = dbg->cnt; cnt > 0; cnt -= ROW_BYTES) {
+ hex_dump_to_buffer(ptr, min(cnt, ROW_BYTES),
+ ROW_BYTES, GROUP_BYTES, dump_buf,
+ sizeof(dump_buf), false);
+ len = scnprintf(dbg->buf + tot, dbg->buf_len - tot,
+ "0x%08x: %s\n",
+ ((int) (unsigned long) ptr) -
+ ((int) (unsigned long) dbg->base),
+ dump_buf);
+
+ ptr += ROW_BYTES;
+ tot += len;
+ if (tot >= dbg->buf_len)
+ break;
+ }
+ /* Disable clock after register access */
+ sde_rotator_clk_ctrl(dbg->mgr, false);
+
+ dbg->buf_len = tot;
+ }
+
+ if (*ppos >= dbg->buf_len)
+ return 0; /* done reading */
+
+ len = min(count, dbg->buf_len - (size_t) *ppos);
+ if (copy_to_user(user_buf, dbg->buf + *ppos, len)) {
+ SDEROT_ERR("failed to copy to user\n");
+ return -EFAULT;
+ }
+
+ *ppos += len; /* increase offset */
+
+ return len;
+}
+
+static const struct file_operations sde_rotator_off_fops = {
+ .open = sde_rotator_debug_base_open,
+ .release = sde_rotator_debug_base_release,
+ .read = sde_rotator_debug_base_offset_read,
+ .write = sde_rotator_debug_base_offset_write,
+};
+
+static const struct file_operations sde_rotator_reg_fops = {
+ .open = sde_rotator_debug_base_open,
+ .release = sde_rotator_debug_base_release,
+ .read = sde_rotator_debug_base_reg_read,
+ .write = sde_rotator_debug_base_reg_write,
+};
+
+int sde_rotator_debug_register_base(struct sde_rotator_device *rot_dev,
+ struct dentry *debugfs_root,
+ const char *name,
+ struct sde_io_data *io_data)
+{
+ struct sde_rotator_debug_base *dbg;
+ struct dentry *ent_off, *ent_reg;
+ char dbgname[80] = "";
+ int prefix_len = 0;
+
+ if (!io_data)
+ return -EINVAL;
+
+ dbg = kzalloc(sizeof(*dbg), GFP_KERNEL);
+ if (!dbg)
+ return -ENOMEM;
+
+ if (name)
+ strlcpy(dbg->name, name, sizeof(dbg->name));
+ dbg->base = io_data->base;
+ dbg->max_offset = io_data->len;
+ dbg->off = 0;
+ dbg->cnt = SDE_ROT_DEFAULT_BASE_REG_CNT;
+
+ if (name) {
+ if (strcmp(name, "sde"))
+ prefix_len = snprintf(dbgname, sizeof(dbgname), "%s_",
+ name);
+ else
+ /*
+ * For SDE Rotator registers block, the IO base address
+ * is based on MDP IO address base. It is necessary to
+ * apply the initial offset to it from the first
+ * regdump setting.
+ */
+ dbg->base += rot_dev->mdata->regdump ?
+ rot_dev->mdata->regdump[0].offset : 0;
+ }
+
+ strlcpy(dbgname + prefix_len, "off", sizeof(dbgname) - prefix_len);
+ ent_off = debugfs_create_file(dbgname, 0644, debugfs_root, dbg,
+ &sde_rotator_off_fops);
+ if (IS_ERR_OR_NULL(ent_off)) {
+ SDEROT_ERR("debugfs_create_file: offset fail\n");
+ goto off_fail;
+ }
+
+ strlcpy(dbgname + prefix_len, "reg", sizeof(dbgname) - prefix_len);
+ ent_reg = debugfs_create_file(dbgname, 0644, debugfs_root, dbg,
+ &sde_rotator_reg_fops);
+ if (IS_ERR_OR_NULL(ent_reg)) {
+ SDEROT_ERR("debugfs_create_file: reg fail\n");
+ goto reg_fail;
+ }
+
+ dbg->mgr = rot_dev->mgr;
+
+ return 0;
+reg_fail:
+ debugfs_remove(ent_off);
+off_fail:
+ kfree(dbg);
+ return -ENODEV;
+}
+
/*
* sde_rotator_create_debugfs - Setup rotator debugfs directory structure.
* @rot_dev: Pointer to rotator device
@@ -1040,6 +1311,20 @@ struct dentry *sde_rotator_create_debugfs(
return NULL;
}
+ if (sde_rotator_debug_register_base(rot_dev, debugfs_root,
+ "sde", &rot_dev->mdata->sde_io)) {
+ SDEROT_ERR("fail create debug register for sde rotator\n");
+ debugfs_remove_recursive(debugfs_root);
+ return NULL;
+ }
+
+ if (sde_rotator_debug_register_base(rot_dev, debugfs_root,
+ "vbif_nrt", &rot_dev->mdata->vbif_nrt_io)) {
+ SDEROT_ERR("fail create debug register for sderot vbif_nrt\n");
+ debugfs_remove_recursive(debugfs_root);
+ return NULL;
+ }
+
return debugfs_root;
}
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_debug.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_debug.h
index dcda54274fad..c2c6f9775602 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_debug.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_debug.h
@@ -44,6 +44,17 @@ void sde_rot_evtlog_tout_handler(bool queue, const char *name, ...);
struct sde_rotator_device;
+struct sde_rotator_debug_base {
+ char name[80];
+ void __iomem *base;
+ size_t off;
+ size_t cnt;
+ size_t max_offset;
+ char *buf;
+ size_t buf_len;
+ struct sde_rot_mgr *mgr;
+};
+
#if defined(CONFIG_DEBUG_FS)
struct dentry *sde_rotator_create_debugfs(
struct sde_rotator_device *rot_dev);
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
index b88f03ce89ae..08075ae90507 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
@@ -305,6 +305,39 @@ static void sde_rotator_buf_queue(struct vb2_buffer *vb)
}
/*
+ * sde_rotator_buf_finish - vb2_ops buf_finish to finalize buffer before going
+ * back to user space
+ * @vb: Pointer to vb2 buffer struct.
+ */
+static void sde_rotator_buf_finish(struct vb2_buffer *vb)
+{
+ struct sde_rotator_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ int i;
+
+ SDEDEV_DBG(ctx->rot_dev->dev,
+ "buf_finish t:%d i:%d s:%d m:%u np:%d up:%lu\n",
+ vb->type, vb->index, vb->state,
+ vb->vb2_queue->memory,
+ vb->num_planes,
+ vb->planes[0].m.userptr);
+
+ if (vb->vb2_queue->memory != VB2_MEMORY_USERPTR)
+ return;
+
+ /*
+ * We use userptr to tunnel fd, and fd can be the same across qbuf
+ * even though the underlying buffer is different. Since vb2 layer
+ * optimizes memory mapping for userptr by first checking if userptr
+ * has changed, it will not trigger put_userptr if fd value does
+ * not change. In order to force buffer release, we need to clear
+ * userptr when the current buffer is done and ready to go back to
+ * user mode. Since 0 is a valid fd, reset userptr to -1 instead.
+ */
+ for (i = 0; i < vb->num_planes; i++)
+ vb->planes[i].m.userptr = ~0;
+}
+
+/*
* sde_rotator_return_all_buffers - Return all buffers with the given status.
* @q: Pointer to vb2 buffer queue struct.
* @state: State of the buffer
@@ -460,6 +493,7 @@ static struct vb2_ops sde_rotator_vb2_q_ops = {
.stop_streaming = sde_rotator_stop_streaming,
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish,
+ .buf_finish = sde_rotator_buf_finish,
};
/*
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 925b8497273a..4e86a3ff820d 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -1502,7 +1502,8 @@ static void sde_hw_rotator_free_rotctx(struct sde_hw_rotator *rot,
ctx->q_id, ctx->timestamp,
atomic_read(&ctx->hwres->num_active));
- rot->rotCtx[ctx->q_id][sde_hw_rotator_get_regdma_ctxidx(ctx)] = NULL;
+ /* Clear rotator context from lookup purpose */
+ sde_hw_rotator_clr_ctx(ctx);
devm_kfree(&rot->pdev->dev, ctx);
}
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h
index 91ac3d0371fa..7aecc3cee210 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h
@@ -345,10 +345,32 @@ static inline void sde_hw_rotator_put_ctx(struct sde_hw_rotator_context *ctx)
{
struct sde_hw_rotator *rot = ctx->rot;
u32 idx = sde_hw_rotator_get_regdma_ctxidx(ctx);
+ unsigned long flags;
+ spin_lock_irqsave(&rot->rotisr_lock, flags);
rot->rotCtx[ctx->q_id][idx] = ctx;
+ spin_unlock_irqrestore(&rot->rotisr_lock, flags);
+
SDEROT_DBG("rotCtx[%d][%d] <== ctx:%p | session-id:%d\n",
ctx->q_id, idx, ctx, ctx->session_id);
}
+/**
+ * sde_hw_rotator_clr_ctx(): Clearing rotator context according to its
+ * timestamp.
+ */
+static inline void sde_hw_rotator_clr_ctx(struct sde_hw_rotator_context *ctx)
+{
+ struct sde_hw_rotator *rot = ctx->rot;
+ u32 idx = sde_hw_rotator_get_regdma_ctxidx(ctx);
+ unsigned long flags;
+
+ spin_lock_irqsave(&rot->rotisr_lock, flags);
+ rot->rotCtx[ctx->q_id][idx] = NULL;
+ spin_unlock_irqrestore(&rot->rotisr_lock, flags);
+
+ SDEROT_DBG("rotCtx[%d][%d] <== null | session-id:%d\n",
+ ctx->q_id, idx, ctx->session_id);
+}
+
#endif /*_SDE_ROTATOR_R3_INTERNAL_H */
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index 0b44896bf6b3..7388dab92c34 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -2153,6 +2153,33 @@ int create_pkt_cmd_session_set_property(
pkt->size += sizeof(u32) + sizeof(*signal_info);
break;
}
+ case HAL_PARAM_VENC_IFRAMESIZE_TYPE:
+ {
+ enum hal_iframesize_type hal =
+ *(enum hal_iframesize_type *)pdata;
+ struct hfi_iframe_size *hfi = (struct hfi_iframe_size *)
+ &pkt->rg_property_data[1];
+
+ switch (hal) {
+ case HAL_IFRAMESIZE_TYPE_DEFAULT:
+ hfi->type = HFI_IFRAME_SIZE_DEFAULT;
+ break;
+ case HAL_IFRAMESIZE_TYPE_MEDIUM:
+ hfi->type = HFI_IFRAME_SIZE_MEDIUM;
+ break;
+ case HAL_IFRAMESIZE_TYPE_HUGE:
+ hfi->type = HFI_IFRAME_SIZE_HIGH;
+ break;
+ case HAL_IFRAMESIZE_TYPE_UNLIMITED:
+ hfi->type = HFI_IFRAME_SIZE_UNLIMITED;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+ pkt->rg_property_data[0] = HFI_PROPERTY_PARAM_VENC_IFRAMESIZE;
+ pkt->size += sizeof(u32) + sizeof(struct hfi_iframe_size);
+ break;
+ }
/* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */
case HAL_CONFIG_BUFFER_REQUIREMENTS:
case HAL_CONFIG_PRIORITY:
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index 3633d1fb3cd1..fbdccea56f67 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -36,7 +36,7 @@
struct msm_vidc_drv *vidc_driver;
-uint32_t msm_vidc_pwr_collapse_delay = 2000;
+uint32_t msm_vidc_pwr_collapse_delay = 3000;
static inline struct msm_vidc_inst *get_vidc_inst(struct file *filp, void *fh)
{
@@ -138,12 +138,20 @@ int msm_v4l2_reqbufs(struct file *file, void *fh,
{
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
int rc = 0;
- if (!b->count)
+ if (!b->count) {
rc = msm_vidc_release_buffers(vidc_inst, b->type);
- if (rc)
- dprintk(VIDC_WARN,
- "Failed in %s for release output buffers\n", __func__);
- return msm_vidc_reqbufs((void *)vidc_inst, b);
+ if (rc)
+ dprintk(VIDC_WARN,
+ "Failed in %s for release output buffers\n",
+ __func__);
+ } else {
+ rc = msm_vidc_reqbufs((void *)vidc_inst, b);
+ if (rc)
+ dprintk(VIDC_WARN,
+ "Failed in %s for buffer requirements\n",
+ __func__);
+ }
+ return rc;
}
int msm_v4l2_prepare_buf(struct file *file, void *fh,
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 0931242a5ec4..4ec331d121d9 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -185,6 +185,13 @@ static const char *const timestamp_mode[] = {
"Ignore",
};
+static const char *const iframe_sizes[] = {
+ "Default",
+ "Medium",
+ "Huge",
+ "Unlimited"
+};
+
static struct msm_vidc_ctrl msm_venc_ctrls[] = {
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD,
@@ -1281,6 +1288,20 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
.step = 1,
.qmenu = NULL,
},
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE,
+ .name = "Bounds of I-frame size",
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_DEFAULT,
+ .maximum = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED,
+ .default_value = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_DEFAULT,
+ .menu_skip_mask = ~(
+ (1 << V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_DEFAULT) |
+ (1 << V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_MEDIUM) |
+ (1 << V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_HUGE) |
+ (1 << V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED)),
+ .qmenu = iframe_sizes,
+ },
};
@@ -2117,6 +2138,19 @@ static inline int venc_v4l2_to_hal(int id, int value)
default:
goto unknown_value;
}
+ case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE:
+ switch (value) {
+ case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_DEFAULT:
+ return HAL_IFRAMESIZE_TYPE_DEFAULT;
+ case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_MEDIUM:
+ return HAL_IFRAMESIZE_TYPE_MEDIUM;
+ case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_HUGE:
+ return HAL_IFRAMESIZE_TYPE_HUGE;
+ case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED:
+ return HAL_IFRAMESIZE_TYPE_UNLIMITED;
+ default:
+ goto unknown_value;
+ }
}
unknown_value:
@@ -2159,6 +2193,7 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
int frameqp = 0;
int pic_order_cnt = 0;
struct hal_video_signal_info signal_info = {0};
+ enum hal_iframesize_type iframesize_type = HAL_IFRAMESIZE_TYPE_DEFAULT;
if (!inst || !inst->core || !inst->core->device) {
dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
@@ -3242,6 +3277,13 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
}
pdata = &enable;
break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE:
+ property_id = HAL_PARAM_VENC_IFRAMESIZE_TYPE;
+ iframesize_type = venc_v4l2_to_hal(
+ V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE,
+ ctrl->val);
+ pdata = &iframesize_type;
+ break;
default:
dprintk(VIDC_ERR, "Unsupported index: %x\n", ctrl->id);
rc = -ENOTSUPP;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 93e32ef4ac35..c4d06b658b30 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -652,10 +652,6 @@ int output_buffer_cache_invalidate(struct msm_vidc_inst *inst,
return -EINVAL;
}
- if (binfo->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return 0;
-
-
for (i = 0; i < binfo->num_planes; i++) {
if (binfo->handle[i]) {
rc = msm_comm_smem_cache_operations(inst,
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
index 011941c6d4eb..2e1df75cb248 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -24,7 +24,7 @@ EXPORT_SYMBOL(msm_vidc_debug_out);
int msm_vidc_fw_debug = 0x18;
int msm_vidc_fw_debug_mode = 1;
int msm_vidc_fw_low_power_mode = 1;
-int msm_vidc_hw_rsp_timeout = 1000;
+int msm_vidc_hw_rsp_timeout = 2000;
bool msm_vidc_fw_coverage = false;
bool msm_vidc_vpe_csc_601_to_709 = false;
bool msm_vidc_dec_dcvs_mode = true;
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index c87b6fc585c7..787ee43ccbd2 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -3407,10 +3407,12 @@ static int __response_handler(struct venus_hfi_device *device)
packets = device->response_pkt;
- raw_packet = kzalloc(VIDC_IFACEQ_VAR_HUGE_PKT_SIZE, GFP_TEMPORARY);
+ raw_packet = device->raw_packet;
+
if (!raw_packet || !packets) {
- dprintk(VIDC_ERR, "%s: Failed to allocate memory\n", __func__);
- kfree(raw_packet);
+ dprintk(VIDC_ERR,
+ "%s: Invalid args : Res packet = %p, Raw packet = %p\n",
+ __func__, packets, raw_packet);
return 0;
}
@@ -3566,7 +3568,6 @@ static int __response_handler(struct venus_hfi_device *device)
exit:
__flush_debug_queue(device, raw_packet);
- kfree(raw_packet);
return packet_count;
}
@@ -4553,6 +4554,13 @@ static struct venus_hfi_device *__add_device(u32 device_id,
goto err_cleanup;
}
+ hdevice->raw_packet =
+ kzalloc(VIDC_IFACEQ_VAR_HUGE_PKT_SIZE, GFP_TEMPORARY);
+ if (!hdevice->raw_packet) {
+ dprintk(VIDC_ERR, "failed to allocate raw packet\n");
+ goto err_cleanup;
+ }
+
rc = __init_regs_and_interrupts(hdevice, res);
if (rc)
goto err_cleanup;
@@ -4590,6 +4598,7 @@ err_cleanup:
if (hdevice->vidc_workq)
destroy_workqueue(hdevice->vidc_workq);
kfree(hdevice->response_pkt);
+ kfree(hdevice->raw_packet);
kfree(hdevice);
exit:
return NULL;
@@ -4631,6 +4640,7 @@ void venus_hfi_delete_device(void *device)
iounmap(dev->hal_data->register_base);
kfree(close->hal_data);
kfree(close->response_pkt);
+ kfree(close->raw_packet);
kfree(close);
break;
}
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.h b/drivers/media/platform/msm/vidc/venus_hfi.h
index 7cc71a470c2e..1d2ca88a3c1d 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.h
+++ b/drivers/media/platform/msm/vidc/venus_hfi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 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
@@ -247,6 +247,7 @@ struct venus_hfi_device {
struct hfi_packetization_ops *pkt_ops;
enum hfi_packetization_type packetization_type;
struct msm_vidc_cb_info *response_pkt;
+ u8 *raw_packet;
struct pm_qos_request qos;
unsigned int skip_pc_count;
struct msm_vidc_capability *sys_init_capabilities;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index aa566159c393..116ce12c8dba 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -242,6 +242,7 @@ enum hal_property {
HAL_PARAM_VENC_SESSION_QP_RANGE_PACKED,
HAL_PARAM_VENC_H264_TRANSFORM_8x8,
HAL_PARAM_VENC_VIDEO_SIGNAL_INFO,
+ HAL_PARAM_VENC_IFRAMESIZE_TYPE,
};
enum hal_domain {
@@ -1002,6 +1003,13 @@ struct hal_video_signal_info {
bool full_range;
};
+enum hal_iframesize_type {
+ HAL_IFRAMESIZE_TYPE_DEFAULT,
+ HAL_IFRAMESIZE_TYPE_MEDIUM,
+ HAL_IFRAMESIZE_TYPE_HUGE,
+ HAL_IFRAMESIZE_TYPE_UNLIMITED,
+};
+
enum vidc_resource_id {
VIDC_RESOURCE_NONE,
VIDC_RESOURCE_OCMEM,
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index 5e5ef6abc303..bb9958b0a819 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -386,6 +386,8 @@ struct hfi_buffer_info {
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x031)
#define HFI_PROPERTY_PARAM_VENC_VQZIP_SEI_TYPE \
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x033)
+#define HFI_PROPERTY_PARAM_VENC_IFRAMESIZE \
+ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x034)
#define HFI_PROPERTY_CONFIG_VENC_COMMON_START \
(HFI_DOMAIN_BASE_VENC + HFI_ARCH_COMMON_OFFSET + 0x6000)
@@ -888,6 +890,14 @@ struct hfi_aspect_ratio {
u32 aspect_height;
};
+#define HFI_IFRAME_SIZE_DEFAULT (HFI_COMMON_BASE + 0x1)
+#define HFI_IFRAME_SIZE_MEDIUM (HFI_COMMON_BASE + 0x2)
+#define HFI_IFRAME_SIZE_HIGH (HFI_COMMON_BASE + 0x3)
+#define HFI_IFRAME_SIZE_UNLIMITED (HFI_COMMON_BASE + 0x4)
+struct hfi_iframe_size {
+ u32 type;
+};
+
#define HFI_MVC_BUFFER_LAYOUT_TOP_BOTTOM (0)
#define HFI_MVC_BUFFER_LAYOUT_SIDEBYSIDE (1)
#define HFI_MVC_BUFFER_LAYOUT_SEQ (2)
diff --git a/drivers/mfd/wcd9xxx-utils.c b/drivers/mfd/wcd9xxx-utils.c
index 344a0d5330aa..2b0a5f8ce7f2 100644
--- a/drivers/mfd/wcd9xxx-utils.c
+++ b/drivers/mfd/wcd9xxx-utils.c
@@ -311,6 +311,7 @@ struct wcd9xxx_pdata *wcd9xxx_populate_dt_data(struct device *dev)
u32 ecpp_dmic_sample_rate = WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED;
u32 dmic_clk_drive = WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED;
u32 prop_val;
+ int rc = 0;
if (!dev || !dev->of_node)
return NULL;
@@ -369,9 +370,13 @@ struct wcd9xxx_pdata *wcd9xxx_populate_dt_data(struct device *dev)
pdata->mclk_rate,
"mad_dmic_rate");
- if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-ecpp-dmic-rate",
- &prop_val)))
- ecpp_dmic_sample_rate = prop_val;
+ if (of_find_property(dev->of_node, "qcom,cdc-ecpp-dmic-rate", NULL)) {
+ rc = wcd9xxx_read_of_property_u32(dev,
+ "qcom,cdc-ecpp-dmic-rate",
+ &prop_val);
+ if (!rc)
+ ecpp_dmic_sample_rate = prop_val;
+ }
pdata->ecpp_dmic_sample_rate = wcd9xxx_validate_dmic_sample_rate(dev,
ecpp_dmic_sample_rate,
@@ -380,13 +385,14 @@ struct wcd9xxx_pdata *wcd9xxx_populate_dt_data(struct device *dev)
if (!(of_property_read_u32(dev->of_node,
"qcom,cdc-dmic-clk-drv-strength",
- &prop_val)))
+ &prop_val))) {
dmic_clk_drive = prop_val;
- if (dmic_clk_drive != 2 && dmic_clk_drive != 4 &&
- dmic_clk_drive != 8 && dmic_clk_drive != 16)
- dev_err(dev, "Invalid cdc-dmic-clk-drv-strength %d\n",
- dmic_clk_drive);
+ if (dmic_clk_drive != 2 && dmic_clk_drive != 4 &&
+ dmic_clk_drive != 8 && dmic_clk_drive != 16)
+ dev_err(dev, "Invalid cdc-dmic-clk-drv-strength %d\n",
+ dmic_clk_drive);
+ }
pdata->dmic_clk_drv = dmic_clk_drive;
diff --git a/drivers/misc/hdcp.c b/drivers/misc/hdcp.c
index 69ec7127102c..56ddf8467d16 100644
--- a/drivers/misc/hdcp.c
+++ b/drivers/misc/hdcp.c
@@ -255,6 +255,15 @@ struct __attribute__ ((__packed__)) hdcp_version_rsp {
uint32_t appversion;
};
+struct __attribute__ ((__packed__)) hdcp_verify_key_req {
+ uint32_t commandid;
+};
+
+struct __attribute__ ((__packed__)) hdcp_verify_key_rsp {
+ uint32_t status;
+ uint32_t commandId;
+};
+
struct __attribute__ ((__packed__)) hdcp_lib_init_req_v1 {
uint32_t commandid;
};
@@ -794,6 +803,48 @@ exit:
return rc;
}
+static int hdcp_lib_verify_keys(struct hdcp_lib_handle *handle)
+{
+ int rc = -EINVAL;
+ struct hdcp_verify_key_req *req_buf;
+ struct hdcp_verify_key_rsp *rsp_buf;
+
+ if (!handle) {
+ pr_err("invalid input\n");
+ goto exit;
+ }
+
+ if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
+ pr_err("app not loaded\n");
+ goto exit;
+ }
+
+ req_buf = (struct hdcp_verify_key_req *)handle->qseecom_handle->sbuf;
+ req_buf->commandid = HDCP_TXMTR_VERIFY_KEY;
+
+ rsp_buf = (struct hdcp_verify_key_rsp *)
+ (handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof(struct hdcp_verify_key_req)));
+
+ rc = qseecom_send_command(handle->qseecom_handle,
+ req_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_verify_key_req)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_verify_key_rsp)));
+
+ if (rc < 0) {
+ pr_err("qseecom cmd failed err = %d\n", rc);
+ goto exit;
+ }
+
+ return rsp_buf->status;
+exit:
+ return rc;
+}
+
+
static int hdcp_app_init_legacy(struct hdcp_lib_handle *handle)
{
int rc = 0;
@@ -1456,10 +1507,12 @@ static bool hdcp_lib_client_feature_supported(void *phdcpcontext)
rc = hdcp_lib_library_load(handle);
if (!rc) {
- pr_debug("HDCP2p2 supported\n");
- handle->feature_supported = true;
+ if (!hdcp_lib_verify_keys(handle)) {
+ pr_debug("HDCP2p2 supported\n");
+ handle->feature_supported = true;
+ supported = true;
+ }
hdcp_lib_library_unload(handle);
- supported = true;
}
exit:
return supported;
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 0bed86d2ccc0..457629ee4bf5 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -2184,6 +2184,7 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)
struct qseecom_load_app_64bit_ireq load_req_64bit;
void *cmd_buf = NULL;
size_t cmd_len;
+ bool first_time = false;
/* Copy the relevant information needed for loading the image */
if (copy_from_user(&load_img_req,
@@ -2255,6 +2256,7 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)
&qseecom.registered_app_list_lock, flags);
ret = 0;
} else {
+ first_time = true;
pr_warn("App (%s) does'nt exist, loading apps for first time\n",
(char *)(load_img_req.img_name));
/* Get the handle of the shared fd */
@@ -2386,8 +2388,15 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)
load_img_req.app_id = app_id;
if (copy_to_user(argp, &load_img_req, sizeof(load_img_req))) {
pr_err("copy_to_user failed\n");
- kzfree(entry);
ret = -EFAULT;
+ if (first_time == true) {
+ spin_lock_irqsave(
+ &qseecom.registered_app_list_lock, flags);
+ list_del(&entry->list);
+ spin_unlock_irqrestore(
+ &qseecom.registered_app_list_lock, flags);
+ kzfree(entry);
+ }
}
loadapp_err:
@@ -8116,11 +8125,12 @@ static int qseecom_check_whitelist_feature(void)
static int qseecom_probe(struct platform_device *pdev)
{
int rc;
- int ret = 0;
+ int i;
uint32_t feature = 10;
struct device *class_dev;
struct msm_bus_scale_pdata *qseecom_platform_support = NULL;
struct qseecom_command_scm_resp resp;
+ struct qseecom_ce_info_use *pce_info_use = NULL;
qseecom.qsee_bw_count = 0;
qseecom.qsee_perf_client = 0;
@@ -8162,7 +8172,7 @@ static int qseecom_probe(struct platform_device *pdev)
class_dev = device_create(driver_class, NULL, qseecom_device_no, NULL,
QSEECOM_DEV);
- if (!class_dev) {
+ if (IS_ERR(class_dev)) {
pr_err("class_device_create failed %d\n", rc);
rc = -ENOMEM;
goto exit_destroy_class;
@@ -8201,7 +8211,7 @@ static int qseecom_probe(struct platform_device *pdev)
qseecom.pdev = class_dev;
/* Create ION msm client */
qseecom.ion_clnt = msm_ion_client_create("qseecom-kernel");
- if (qseecom.ion_clnt == NULL) {
+ if (IS_ERR_OR_NULL(qseecom.ion_clnt)) {
pr_err("Ion client cannot be created\n");
rc = -ENOMEM;
goto exit_del_cdev;
@@ -8263,14 +8273,14 @@ static int qseecom_probe(struct platform_device *pdev)
pr_debug("CE operating frequency is not defined, setting to default 100MHZ\n");
qseecom.ce_opp_freq_hz = QSEE_CE_CLK_100MHZ;
}
- ret = __qseecom_init_clk(CLK_QSEE);
- if (ret)
+ rc = __qseecom_init_clk(CLK_QSEE);
+ if (rc)
goto exit_destroy_ion_client;
if ((qseecom.qsee.instance != qseecom.ce_drv.instance) &&
(qseecom.support_pfe || qseecom.support_fde)) {
- ret = __qseecom_init_clk(CLK_CE_DRV);
- if (ret) {
+ rc = __qseecom_init_clk(CLK_CE_DRV);
+ if (rc) {
__qseecom_deinit_clk(CLK_QSEE);
goto exit_destroy_ion_client;
}
@@ -8324,9 +8334,14 @@ static int qseecom_probe(struct platform_device *pdev)
} else {
pr_err("Fail to get secure app region info\n");
rc = -EINVAL;
- goto exit_destroy_ion_client;
+ goto exit_deinit_clock;
+ }
+ rc = __qseecom_enable_clk(CLK_QSEE);
+ if (rc) {
+ pr_err("CLK_QSEE enabling failed (%d)\n", rc);
+ rc = -EIO;
+ goto exit_deinit_clock;
}
- __qseecom_enable_clk(CLK_QSEE);
rc = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
cmd_buf, cmd_len,
&resp, sizeof(resp));
@@ -8335,7 +8350,7 @@ static int qseecom_probe(struct platform_device *pdev)
pr_err("send secapp reg fail %d resp.res %d\n",
rc, resp.result);
rc = -EINVAL;
- goto exit_destroy_ion_client;
+ goto exit_deinit_clock;
}
}
/*
@@ -8371,7 +8386,28 @@ static int qseecom_probe(struct platform_device *pdev)
atomic_set(&qseecom.qseecom_state, QSEECOM_STATE_READY);
return 0;
+exit_deinit_clock:
+ __qseecom_deinit_clk(CLK_QSEE);
+ if ((qseecom.qsee.instance != qseecom.ce_drv.instance) &&
+ (qseecom.support_pfe || qseecom.support_fde))
+ __qseecom_deinit_clk(CLK_CE_DRV);
exit_destroy_ion_client:
+ if (qseecom.ce_info.fde) {
+ pce_info_use = qseecom.ce_info.fde;
+ for (i = 0; i < qseecom.ce_info.num_fde; i++) {
+ kzfree(pce_info_use->ce_pipe_entry);
+ pce_info_use++;
+ }
+ kfree(qseecom.ce_info.fde);
+ }
+ if (qseecom.ce_info.pfe) {
+ pce_info_use = qseecom.ce_info.pfe;
+ for (i = 0; i < qseecom.ce_info.num_pfe; i++) {
+ kzfree(pce_info_use->ce_pipe_entry);
+ pce_info_use++;
+ }
+ kfree(qseecom.ce_info.pfe);
+ }
ion_client_destroy(qseecom.ion_clnt);
exit_del_cdev:
cdev_del(&qseecom.cdev);
diff --git a/drivers/net/wireless/ath/wil6210/pmc.c b/drivers/net/wireless/ath/wil6210/pmc.c
index 5ca0307a3274..b9faae0278c9 100644
--- a/drivers/net/wireless/ath/wil6210/pmc.c
+++ b/drivers/net/wireless/ath/wil6210/pmc.c
@@ -54,6 +54,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
struct pmc_ctx *pmc = &wil->pmc;
struct device *dev = wil_to_dev(wil);
struct wmi_pmc_cmd pmc_cmd = {0};
+ int last_cmd_err = -ENOMEM;
mutex_lock(&pmc->lock);
@@ -62,6 +63,29 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
wil_err(wil, "%s: ERROR pmc is already allocated\n", __func__);
goto no_release_err;
}
+ if ((num_descriptors <= 0) || (descriptor_size <= 0)) {
+ wil_err(wil,
+ "Invalid params num_descriptors(%d), descriptor_size(%d)\n",
+ num_descriptors, descriptor_size);
+ last_cmd_err = -EINVAL;
+ goto no_release_err;
+ }
+
+ if (num_descriptors > (1 << WIL_RING_SIZE_ORDER_MAX)) {
+ wil_err(wil,
+ "num_descriptors(%d) exceeds max ring size %d\n",
+ num_descriptors, 1 << WIL_RING_SIZE_ORDER_MAX);
+ last_cmd_err = -EINVAL;
+ goto no_release_err;
+ }
+
+ if (num_descriptors > INT_MAX / descriptor_size) {
+ wil_err(wil,
+ "Overflow in num_descriptors(%d)*descriptor_size(%d)\n",
+ num_descriptors, descriptor_size);
+ last_cmd_err = -EINVAL;
+ goto no_release_err;
+ }
pmc->num_descriptors = num_descriptors;
pmc->descriptor_size = descriptor_size;
@@ -189,7 +213,7 @@ release_pmc_skb_list:
pmc->descriptors = NULL;
no_release_err:
- pmc->last_cmd_status = -ENOMEM;
+ pmc->last_cmd_status = last_cmd_err;
mutex_unlock(&pmc->lock);
}
@@ -295,7 +319,7 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
size_t retval = 0;
unsigned long long idx;
loff_t offset;
- size_t pmc_size = pmc->descriptor_size * pmc->num_descriptors;
+ size_t pmc_size;
mutex_lock(&pmc->lock);
@@ -306,6 +330,8 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
return -EPERM;
}
+ pmc_size = pmc->descriptor_size * pmc->num_descriptors;
+
wil_dbg_misc(wil,
"%s: size %u, pos %lld\n",
__func__, (unsigned)count, *f_pos);
@@ -345,7 +371,18 @@ loff_t wil_pmc_llseek(struct file *filp, loff_t off, int whence)
loff_t newpos;
struct wil6210_priv *wil = filp->private_data;
struct pmc_ctx *pmc = &wil->pmc;
- size_t pmc_size = pmc->descriptor_size * pmc->num_descriptors;
+ size_t pmc_size;
+
+ mutex_lock(&pmc->lock);
+
+ if (!wil_is_pmc_allocated(pmc)) {
+ wil_err(wil, "error, pmc is not allocated!\n");
+ pmc->last_cmd_status = -EPERM;
+ mutex_unlock(&pmc->lock);
+ return -EPERM;
+ }
+
+ pmc_size = pmc->descriptor_size * pmc->num_descriptors;
switch (whence) {
case 0: /* SEEK_SET */
@@ -361,15 +398,21 @@ loff_t wil_pmc_llseek(struct file *filp, loff_t off, int whence)
break;
default: /* can't happen */
- return -EINVAL;
+ newpos = -EINVAL;
+ goto out;
}
- if (newpos < 0)
- return -EINVAL;
+ if (newpos < 0) {
+ newpos = -EINVAL;
+ goto out;
+ }
if (newpos > pmc_size)
newpos = pmc_size;
filp->f_pos = newpos;
+out:
+ mutex_unlock(&pmc->lock);
+
return newpos;
}
diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c
index 154310020997..2dd18dd78677 100644
--- a/drivers/nfc/nq-nci.c
+++ b/drivers/nfc/nq-nci.c
@@ -53,6 +53,7 @@ struct nqx_dev {
struct mutex read_mutex;
struct i2c_client *client;
struct miscdevice nqx_device;
+ union nqx_uinfo nqx_info;
/* NFC GPIO variables */
unsigned int irq_gpio;
unsigned int en_gpio;
@@ -467,6 +468,25 @@ int nfc_ioctl_core_reset_ntf(struct file *filp)
return nqx_dev->core_reset_ntf;
}
+/*
+ * Inside nfc_ioctl_nfcc_info
+ *
+ * @brief nfc_ioctl_nfcc_info
+ *
+ * Check the NQ Chipset and firmware version details
+ */
+unsigned int nfc_ioctl_nfcc_info(struct file *filp, unsigned long arg)
+{
+ unsigned int r = 0;
+ struct nqx_dev *nqx_dev = filp->private_data;
+
+ r = nqx_dev->nqx_info.i;
+ dev_dbg(&nqx_dev->client->dev,
+ "nqx nfc : nfc_ioctl_nfcc_info r = %d\n", r);
+
+ return r;
+}
+
static long nfc_ioctl(struct file *pfile, unsigned int cmd,
unsigned long arg)
{
@@ -489,6 +509,9 @@ static long nfc_ioctl(struct file *pfile, unsigned int cmd,
case NFCC_INITIAL_CORE_RESET_NTF:
r = nfc_ioctl_core_reset_ntf(pfile);
break;
+ case NFCC_GET_INFO:
+ r = nfc_ioctl_nfcc_info(pfile, arg);
+ break;
default:
r = -ENOIOCTLCMD;
}
@@ -508,13 +531,16 @@ static const struct file_operations nfc_dev_fops = {
};
/* Check for availability of NQ_ NFC controller hardware */
-static int nfcc_hw_check(struct i2c_client *client, unsigned int enable_gpio)
+static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
{
int ret = 0;
unsigned char raw_nci_reset_cmd[] = {0x20, 0x00, 0x01, 0x00};
+ unsigned char raw_nci_init_cmd[] = {0x20, 0x01, 0x00};
+ unsigned char nci_init_rsp[28];
unsigned char nci_reset_rsp[6];
-
+ unsigned char init_rsp_len = 0;
+ unsigned int enable_gpio = nqx_dev->en_gpio;
/* making sure that the NFCC starts in a clean state. */
gpio_set_value(enable_gpio, 0);/* ULPM: Disable */
/* hardware dependent delay */
@@ -536,16 +562,75 @@ static int nfcc_hw_check(struct i2c_client *client, unsigned int enable_gpio)
/* Read Response of RESET command */
ret = i2c_master_recv(client, nci_reset_rsp,
- sizeof(nci_reset_rsp));
+ sizeof(nci_reset_rsp));
dev_err(&client->dev,
- "%s: - nq - reset cmd answer : NfcNciRx %x %x %x\n",
- __func__, nci_reset_rsp[0],
- nci_reset_rsp[1], nci_reset_rsp[2]);
+ "%s: - nq - reset cmd answer : NfcNciRx %x %x %x\n",
+ __func__, nci_reset_rsp[0],
+ nci_reset_rsp[1], nci_reset_rsp[2]);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "%s: - i2c_master_recv Error\n", __func__);
+ goto err_nfcc_hw_check;
+ }
+ ret = i2c_master_send(client, raw_nci_init_cmd,
+ sizeof(raw_nci_init_cmd));
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "%s: - i2c_master_send Error\n", __func__);
+ goto err_nfcc_hw_check;
+ }
+ /* hardware dependent delay */
+ msleep(30);
+ /* Read Response of INIT command */
+ ret = i2c_master_recv(client, nci_init_rsp,
+ sizeof(nci_init_rsp));
if (ret < 0) {
dev_err(&client->dev,
"%s: - i2c_master_recv Error\n", __func__);
goto err_nfcc_hw_check;
}
+ init_rsp_len = 2 + nci_init_rsp[2]; /*payload + len*/
+ if (init_rsp_len > PAYLOAD_HEADER_LENGTH) {
+ nqx_dev->nqx_info.info.chip_type =
+ nci_init_rsp[init_rsp_len - 3];
+ nqx_dev->nqx_info.info.rom_version =
+ nci_init_rsp[init_rsp_len - 2];
+ nqx_dev->nqx_info.info.fw_major =
+ nci_init_rsp[init_rsp_len - 1];
+ nqx_dev->nqx_info.info.fw_minor =
+ nci_init_rsp[init_rsp_len];
+ }
+ dev_dbg(&nqx_dev->client->dev, "NQ NFCC chip_type = %x\n",
+ nqx_dev->nqx_info.info.chip_type);
+ dev_dbg(&nqx_dev->client->dev, "NQ fw version = %x.%x.%x\n",
+ nqx_dev->nqx_info.info.rom_version,
+ nqx_dev->nqx_info.info.fw_major,
+ nqx_dev->nqx_info.info.fw_minor);
+
+ switch (nqx_dev->nqx_info.info.chip_type) {
+ case NFCC_NQ_210:
+ dev_dbg(&client->dev,
+ "%s: ## NFCC == NQ210 ##\n", __func__);
+ break;
+ case NFCC_NQ_220:
+ dev_dbg(&client->dev,
+ "%s: ## NFCC == NQ220 ##\n", __func__);
+ break;
+ case NFCC_NQ_310:
+ dev_dbg(&client->dev,
+ "%s: ## NFCC == NQ310 ##\n", __func__);
+ break;
+ case NFCC_NQ_330:
+ dev_dbg(&client->dev,
+ "%s: ## NFCC == NQ330 ##\n", __func__);
+ break;
+ default:
+ dev_err(&client->dev,
+ "%s: - NFCC HW not Supported\n", __func__);
+ break;
+ }
+
+ /*Disable NFC by default to save power on boot*/
gpio_set_value(enable_gpio, 0);/* ULPM: Disable */
ret = 0;
goto done;
@@ -566,9 +651,7 @@ done:
static int nqx_clock_select(struct nqx_dev *nqx_dev)
{
int r = 0;
-
- nqx_dev->s_clk =
- clk_get(&nqx_dev->client->dev, "ref_clk");
+ nqx_dev->s_clk = clk_get(&nqx_dev->client->dev, "ref_clk");
if (nqx_dev->s_clk == NULL)
goto err_clk;
@@ -867,8 +950,7 @@ static int nqx_probe(struct i2c_client *client,
* present before attempting further hardware initialisation.
*
*/
-
- r = nfcc_hw_check(client, platform_data->en_gpio);
+ r = nfcc_hw_check(client, nqx_dev);
if (r) {
/* make sure NFCC is not enabled */
gpio_set_value(platform_data->en_gpio, 0);
diff --git a/drivers/nfc/nq-nci.h b/drivers/nfc/nq-nci.h
index d62100c2d15a..c635e818b1f3 100644
--- a/drivers/nfc/nq-nci.h
+++ b/drivers/nfc/nq-nci.h
@@ -22,6 +22,7 @@
#include <linux/ioctl.h>
#include <linux/miscdevice.h>
+#include <linux/nfcinfo.h>
#define NFC_SET_PWR _IOW(0xE9, 0x01, unsigned int)
#define ESE_SET_PWR _IOW(0xE9, 0x02, unsigned int)
@@ -42,4 +43,12 @@ enum nfcc_initial_core_reset_ntf {
DEFAULT_INITIAL_CORE_RESET_NTF, /*2*/
};
+enum nfcc_chip_variant {
+ NFCC_NQ_210 = 0x48, /**< NFCC NQ210 */
+ NFCC_NQ_220 = 0x58, /**< NFCC NQ220 */
+ NFCC_NQ_310 = 0x40, /**< NFCC NQ310 */
+ NFCC_NQ_330 = 0x51, /**< NFCC NQ330 */
+ NFCC_NOT_SUPPORTED = 0xFF /**< NFCC is not supported */
+};
+
#endif
diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c
index 14af8ca66d1c..240bf2903308 100644
--- a/drivers/pci/host/pci-msm.c
+++ b/drivers/pci/host/pci-msm.c
@@ -619,6 +619,7 @@ struct msm_pcie_dev_t {
bool ext_ref_clk;
bool common_phy;
uint32_t ep_latency;
+ uint32_t wr_halt_size;
uint32_t cpl_timeout;
uint32_t current_bdf;
short current_short_bdf;
@@ -1976,6 +1977,8 @@ static void msm_pcie_show_status(struct msm_pcie_dev_t *dev)
dev->common_phy);
PCIE_DBG_FS(dev, "ep_latency: %dms\n",
dev->ep_latency);
+ PCIE_DBG_FS(dev, "wr_halt_size: 0x%x\n",
+ dev->wr_halt_size);
PCIE_DBG_FS(dev, "cpl_timeout: 0x%x\n",
dev->cpl_timeout);
PCIE_DBG_FS(dev, "current_bdf: 0x%x\n",
@@ -4495,8 +4498,19 @@ int msm_pcie_enable(struct msm_pcie_dev_t *dev, u32 options)
if (dev->use_msi) {
PCIE_DBG(dev, "RC%d: enable WR halt.\n", dev->rc_idx);
- msm_pcie_write_mask(dev->parf +
- PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT, 0, BIT(31));
+ val = dev->wr_halt_size ? dev->wr_halt_size :
+ readl_relaxed(dev->parf +
+ PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
+
+ msm_pcie_write_reg(dev->parf,
+ PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT,
+ BIT(31) | val);
+
+ PCIE_DBG(dev,
+ "RC%d: PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT: 0x%x.\n",
+ dev->rc_idx,
+ readl_relaxed(dev->parf +
+ PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT));
}
mutex_lock(&com_phy_lock);
@@ -5385,9 +5399,6 @@ static irqreturn_t handle_linkdown_irq(int irq, void *data)
dev->link_status = MSM_PCIE_LINK_DISABLED;
dev->shadow_en = false;
- pcie_phy_dump(dev);
- pcie_parf_dump(dev);
-
if (dev->linkdown_panic)
panic("User has chosen to panic on linkdown\n");
@@ -5420,7 +5431,7 @@ static irqreturn_t handle_msi_irq(int irq, void *data)
struct msm_pcie_dev_t *dev = data;
void __iomem *ctrl_status;
- PCIE_DBG(dev, "irq=%d\n", irq);
+ PCIE_DUMP(dev, "irq: %d\n", irq);
/* check for set bits, clear it by setting that bit
and trigger corresponding irq */
@@ -5696,7 +5707,7 @@ static int arch_setup_msi_irq_qgic(struct pci_dev *pdev,
irq_set_msi_desc(firstirq, desc);
msg.address_hi = 0;
msg.address_lo = dev->msi_gicm_addr;
- msg.data = dev->msi_gicm_base;
+ msg.data = dev->msi_gicm_base + (firstirq - dev->msi[0].num);
write_msi_msg(firstirq, &msg);
return 0;
@@ -6071,6 +6082,18 @@ static int msm_pcie_probe(struct platform_device *pdev)
PCIE_DBG(&msm_pcie_dev[rc_idx], "RC%d: ep-latency: 0x%x.\n",
rc_idx, msm_pcie_dev[rc_idx].ep_latency);
+ msm_pcie_dev[rc_idx].wr_halt_size = 0;
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,wr-halt-size",
+ &msm_pcie_dev[rc_idx].wr_halt_size);
+ if (ret)
+ PCIE_DBG(&msm_pcie_dev[rc_idx],
+ "RC%d: wr-halt-size not specified in dt. Use default value.\n",
+ rc_idx);
+ else
+ PCIE_DBG(&msm_pcie_dev[rc_idx], "RC%d: wr-halt-size: 0x%x.\n",
+ rc_idx, msm_pcie_dev[rc_idx].wr_halt_size);
+
msm_pcie_dev[rc_idx].cpl_timeout = 0;
ret = of_property_read_u32((&pdev->dev)->of_node,
"qcom,cpl-timeout",
diff --git a/drivers/phy/phy-qcom-ufs-qmp-v3.h b/drivers/phy/phy-qcom-ufs-qmp-v3.h
index 8b1e03eab639..d5e49c281278 100644
--- a/drivers/phy/phy-qcom-ufs-qmp-v3.h
+++ b/drivers/phy/phy-qcom-ufs-qmp-v3.h
@@ -225,22 +225,22 @@ static struct ufs_qcom_phy_calibration phy_cal_table_rate_A_3_0_0[] = {
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE_INITVAL1, 0xFF),
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00),
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_DEC_START_MODE0, 0x82),
- UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_CP_CTRL_MODE0, 0x06),
+ UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_CP_CTRL_MODE0, 0x08),
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
- UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_PLL_CCTRL_MODE0, 0x36),
+ UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_PLL_CCTRL_MODE0, 0x34),
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x3F),
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
- UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE1_MODE0, 0xDA),
+ UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE1_MODE0, 0xCB),
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE2_MODE0, 0x01),
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_LOCK_CMP1_MODE0, 0xFF),
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_LOCK_CMP2_MODE0, 0x0C),
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_DEC_START_MODE1, 0x98),
- UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_CP_CTRL_MODE1, 0x06),
+ UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_CP_CTRL_MODE1, 0x08),
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
- UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_PLL_CCTRL_MODE1, 0x36),
+ UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_PLL_CCTRL_MODE1, 0x34),
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x3F),
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
- UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE1_MODE1, 0xC1),
+ UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE1_MODE1, 0xB2),
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_LOCK_CMP2_MODE1, 0x0F),
diff --git a/drivers/pinctrl/qcom/pinctrl-msmfalcon.c b/drivers/pinctrl/qcom/pinctrl-msmfalcon.c
index 45db409eb7c1..91bbce2ce1d1 100644
--- a/drivers/pinctrl/qcom/pinctrl-msmfalcon.c
+++ b/drivers/pinctrl/qcom/pinctrl-msmfalcon.c
@@ -354,6 +354,8 @@ enum msmfalcon_functions {
msm_mux_blsp_i2c2,
msm_mux_phase_flag31,
msm_mux_blsp_spi3,
+ msm_mux_blsp_spi3_cs1,
+ msm_mux_blsp_spi3_cs2,
msm_mux_wlan1_adc1,
msm_mux_atest_usb13,
msm_mux_tgu_ch1,
@@ -380,7 +382,10 @@ enum msmfalcon_functions {
msm_mux_blsp_spi4,
msm_mux_pri_mi2s,
msm_mux_phase_flag26,
- msm_mux_qdss_cti,
+ msm_mux_qdss_cti0_a,
+ msm_mux_qdss_cti0_b,
+ msm_mux_qdss_cti1_a,
+ msm_mux_qdss_cti1_b,
msm_mux_DP_HOT,
msm_mux_pri_mi2s_ws,
msm_mux_phase_flag27,
@@ -402,7 +407,8 @@ enum msmfalcon_functions {
msm_mux_phase_flag13,
msm_mux_vsense_mode,
msm_mux_blsp_spi7,
- msm_mux_BLSP_UART,
+ msm_mux_blsp_uart6_a,
+ msm_mux_blsp_uart6_b,
msm_mux_sec_mi2s,
msm_mux_sndwire_clk,
msm_mux_phase_flag17,
@@ -415,13 +421,15 @@ enum msmfalcon_functions {
msm_mux_vfr_1,
msm_mux_phase_flag20,
msm_mux_NFC_INT,
- msm_mux_blsp_spi,
+ msm_mux_blsp_spi8_cs1,
+ msm_mux_blsp_spi8_cs2,
msm_mux_m_voc,
msm_mux_phase_flag21,
msm_mux_NFC_EN,
msm_mux_phase_flag22,
msm_mux_NFC_DWL,
- msm_mux_BLSP_I2C,
+ msm_mux_blsp_i2c8_a,
+ msm_mux_blsp_i2c8_b,
msm_mux_phase_flag23,
msm_mux_NFC_ESE,
msm_mux_pwr_modem,
@@ -519,10 +527,15 @@ enum msmfalcon_functions {
msm_mux_atest_char0,
msm_mux_US_EURO,
msm_mux_LCD_BACKLIGHT,
- msm_mux_blsp_spi8,
+ msm_mux_blsp_spi8_a,
+ msm_mux_blsp_spi8_b,
msm_mux_sp_cmu,
- msm_mux_NAV_PPS,
- msm_mux_GPS_TX,
+ msm_mux_nav_pps_a,
+ msm_mux_nav_pps_b,
+ msm_mux_nav_pps_c,
+ msm_mux_gps_tx_a,
+ msm_mux_gps_tx_b,
+ msm_mux_gps_tx_c,
msm_mux_adsp_ext,
msm_mux_TS_RESET,
msm_mux_ssc_irq,
@@ -560,16 +573,23 @@ static const char * const blsp_spi1_groups[] = {
"gpio0", "gpio1", "gpio2", "gpio3", "gpio46",
};
static const char * const gpio_groups[] = {
- "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio6", "gpio7", "gpio8",
- "gpio9", "gpio10", "gpio11", "gpio14", "gpio15", "gpio16", "gpio17",
- "gpio18", "gpio19", "gpio20", "gpio21", "gpio22", "gpio23", "gpio24",
- "gpio25", "gpio32", "gpio33", "gpio34", "gpio35", "gpio36", "gpio37",
- "gpio38", "gpio39", "gpio57", "gpio58", "gpio59", "gpio61", "gpio65",
- "gpio81", "gpio82", "gpio83", "gpio84", "gpio85", "gpio86", "gpio87",
- "gpio88", "gpio89", "gpio90", "gpio91", "gpio92", "gpio93", "gpio94",
- "gpio95", "gpio96", "gpio97", "gpio98", "gpio99", "gpio100", "gpio101",
- "gpio102", "gpio103", "gpio104", "gpio105", "gpio106", "gpio107",
- "gpio108", "gpio109", "gpio110", "gpio111", "gpio112", "gpio113",
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+ "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+ "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+ "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+ "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+ "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+ "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+ "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+ "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+ "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
+ "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91",
+ "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98",
+ "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104",
+ "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110",
+ "gpio111", "gpio112", "gpio113",
};
static const char * const blsp_uim1_groups[] = {
"gpio0", "gpio1",
@@ -599,7 +619,13 @@ static const char * const phase_flag31_groups[] = {
"gpio6",
};
static const char * const blsp_spi3_groups[] = {
- "gpio8", "gpio9", "gpio10", "gpio11", "gpio30", "gpio65",
+ "gpio8", "gpio9", "gpio10", "gpio11",
+};
+static const char * const blsp_spi3_cs1_groups[] = {
+ "gpio30",
+};
+static const char * const blsp_spi3_cs2_groups[] = {
+ "gpio65",
};
static const char * const wlan1_adc1_groups[] = {
"gpio8",
@@ -679,9 +705,17 @@ static const char * const pri_mi2s_groups[] = {
static const char * const phase_flag26_groups[] = {
"gpio12",
};
-static const char * const qdss_cti_groups[] = {
- "gpio12", "gpio13", "gpio21", "gpio49", "gpio50", "gpio53", "gpio55",
- "gpio66",
+static const char * const qdss_cti0_a_groups[] = {
+ "gpio49", "gpio50",
+};
+static const char * const qdss_cti0_b_groups[] = {
+ "gpio13", "gpio21",
+};
+static const char * const qdss_cti1_a_groups[] = {
+ "gpio53", "gpio55",
+};
+static const char * const qdss_cti1_b_groups[] = {
+ "gpio12", "gpio66",
};
static const char * const DP_HOT_groups[] = {
"gpio13",
@@ -714,10 +748,10 @@ static const char * const blsp_i2c5_groups[] = {
"gpio18", "gpio19",
};
static const char * const blsp_spi6_groups[] = {
- "gpio20", "gpio21", "gpio22", "gpio23",
+ "gpio49", "gpio52", "gpio22", "gpio23",
};
static const char * const blsp_uart2_groups[] = {
- "gpio20", "gpio21", "gpio22", "gpio23",
+ "gpio4", "gpio5", "gpio6", "gpio7",
};
static const char * const blsp_uim6_groups[] = {
"gpio20", "gpio21",
@@ -746,9 +780,11 @@ static const char * const vsense_mode_groups[] = {
static const char * const blsp_spi7_groups[] = {
"gpio24", "gpio25", "gpio26", "gpio27",
};
-static const char * const BLSP_UART_groups[] = {
- "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29", "gpio30",
- "gpio31",
+static const char * const blsp_uart6_a_groups[] = {
+ "gpio24", "gpio25", "gpio26", "gpio27",
+};
+static const char * const blsp_uart6_b_groups[] = {
+ "gpio28", "gpio29", "gpio30", "gpio31",
};
static const char * const sec_mi2s_groups[] = {
"gpio24", "gpio25", "gpio26", "gpio27", "gpio62",
@@ -786,9 +822,11 @@ static const char * const phase_flag20_groups[] = {
static const char * const NFC_INT_groups[] = {
"gpio28",
};
-static const char * const blsp_spi_groups[] = {
- "gpio28", "gpio29", "gpio30", "gpio31", "gpio40", "gpio41", "gpio44",
- "gpio52",
+static const char * const blsp_spi8_a_groups[] = {
+ "gpio28", "gpio29", "gpio30", "gpio31",
+};
+static const char * const blsp_spi8_b_groups[] = {
+ "gpio40", "gpio41", "gpio44", "gpio52",
};
static const char * const m_voc_groups[] = {
"gpio28",
@@ -805,8 +843,11 @@ static const char * const phase_flag22_groups[] = {
static const char * const NFC_DWL_groups[] = {
"gpio30",
};
-static const char * const BLSP_I2C_groups[] = {
- "gpio30", "gpio31", "gpio44", "gpio52",
+static const char * const blsp_i2c8_a_groups[] = {
+ "gpio30", "gpio31",
+};
+static const char * const blsp_i2c8_b_groups[] = {
+ "gpio44", "gpio52",
};
static const char * const phase_flag23_groups[] = {
"gpio30",
@@ -1099,17 +1140,32 @@ static const char * const US_EURO_groups[] = {
static const char * const LCD_BACKLIGHT_groups[] = {
"gpio64",
};
-static const char * const blsp_spi8_groups[] = {
- "gpio64", "gpio76",
+static const char * const blsp_spi8_cs1_groups[] = {
+ "gpio64",
+};
+static const char * const blsp_spi8_cs2_groups[] = {
+ "gpio76",
};
static const char * const sp_cmu_groups[] = {
"gpio64",
};
-static const char * const NAV_PPS_groups[] = {
- "gpio65", "gpio65", "gpio80", "gpio80", "gpio98", "gpio98",
+static const char * const nav_pps_a_groups[] = {
+ "gpio65",
};
-static const char * const GPS_TX_groups[] = {
- "gpio65", "gpio80", "gpio98",
+static const char * const nav_pps_b_groups[] = {
+ "gpio98",
+};
+static const char * const nav_pps_c_groups[] = {
+ "gpio80",
+};
+static const char * const gps_tx_a_groups[] = {
+ "gpio65",
+};
+static const char * const gps_tx_b_groups[] = {
+ "gpio98",
+};
+static const char * const gps_tx_c_groups[] = {
+ "gpio80",
};
static const char * const adsp_ext_groups[] = {
"gpio65",
@@ -1216,6 +1272,8 @@ static const struct msm_function msmfalcon_functions[] = {
FUNCTION(blsp_i2c2),
FUNCTION(phase_flag31),
FUNCTION(blsp_spi3),
+ FUNCTION(blsp_spi3_cs1),
+ FUNCTION(blsp_spi3_cs2),
FUNCTION(wlan1_adc1),
FUNCTION(atest_usb13),
FUNCTION(tgu_ch1),
@@ -1242,7 +1300,10 @@ static const struct msm_function msmfalcon_functions[] = {
FUNCTION(blsp_spi4),
FUNCTION(pri_mi2s),
FUNCTION(phase_flag26),
- FUNCTION(qdss_cti),
+ FUNCTION(qdss_cti0_a),
+ FUNCTION(qdss_cti0_b),
+ FUNCTION(qdss_cti1_a),
+ FUNCTION(qdss_cti1_b),
FUNCTION(DP_HOT),
FUNCTION(pri_mi2s_ws),
FUNCTION(phase_flag27),
@@ -1264,7 +1325,8 @@ static const struct msm_function msmfalcon_functions[] = {
FUNCTION(phase_flag13),
FUNCTION(vsense_mode),
FUNCTION(blsp_spi7),
- FUNCTION(BLSP_UART),
+ FUNCTION(blsp_uart6_a),
+ FUNCTION(blsp_uart6_b),
FUNCTION(sec_mi2s),
FUNCTION(sndwire_clk),
FUNCTION(phase_flag17),
@@ -1277,13 +1339,15 @@ static const struct msm_function msmfalcon_functions[] = {
FUNCTION(vfr_1),
FUNCTION(phase_flag20),
FUNCTION(NFC_INT),
- FUNCTION(blsp_spi),
+ FUNCTION(blsp_spi8_cs1),
+ FUNCTION(blsp_spi8_cs2),
FUNCTION(m_voc),
FUNCTION(phase_flag21),
FUNCTION(NFC_EN),
FUNCTION(phase_flag22),
FUNCTION(NFC_DWL),
- FUNCTION(BLSP_I2C),
+ FUNCTION(blsp_i2c8_a),
+ FUNCTION(blsp_i2c8_b),
FUNCTION(phase_flag23),
FUNCTION(NFC_ESE),
FUNCTION(pwr_modem),
@@ -1381,10 +1445,15 @@ static const struct msm_function msmfalcon_functions[] = {
FUNCTION(atest_char0),
FUNCTION(US_EURO),
FUNCTION(LCD_BACKLIGHT),
- FUNCTION(blsp_spi8),
+ FUNCTION(blsp_spi8_a),
+ FUNCTION(blsp_spi8_b),
FUNCTION(sp_cmu),
- FUNCTION(NAV_PPS),
- FUNCTION(GPS_TX),
+ FUNCTION(nav_pps_a),
+ FUNCTION(nav_pps_b),
+ FUNCTION(nav_pps_c),
+ FUNCTION(gps_tx_a),
+ FUNCTION(gps_tx_b),
+ FUNCTION(gps_tx_c),
FUNCTION(adsp_ext),
FUNCTION(TS_RESET),
FUNCTION(ssc_irq),
@@ -1426,13 +1495,14 @@ static const struct msm_pingroup msmfalcon_groups[] = {
NA, NA),
PINGROUP(3, SOUTH, blsp_spi1, blsp_uart1, blsp_i2c1, ddr_bist, NA, NA,
atest_tsens2, atest_usb1, NA),
- PINGROUP(4, NORTH, blsp_spi2, blsp_uim2, NA, phase_flag3, NA, NA, NA,
- NA, NA),
- PINGROUP(5, SOUTH, blsp_spi2, blsp_uim2, NA, phase_flag14, NA, NA, NA,
- NA, NA),
- PINGROUP(6, SOUTH, blsp_spi2, blsp_i2c2, NA, phase_flag31, NA, NA, NA,
+ PINGROUP(4, NORTH, blsp_spi2, blsp_uim2, blsp_uart2, phase_flag3, NA,
+ NA, NA, NA, NA),
+ PINGROUP(5, SOUTH, blsp_spi2, blsp_uim2, blsp_uart2, phase_flag14, NA,
+ NA, NA, NA, NA),
+ PINGROUP(6, SOUTH, blsp_spi2, blsp_i2c2, blsp_uart2, phase_flag31, NA,
+ NA, NA, NA, NA),
+ PINGROUP(7, SOUTH, blsp_spi2, blsp_i2c2, blsp_uart2, NA, NA, NA, NA,
NA, NA),
- PINGROUP(7, SOUTH, blsp_spi2, blsp_i2c2, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(8, NORTH, blsp_spi3, ddr_bist, NA, NA, NA, wlan1_adc1,
atest_usb13, bimc_dte1, NA),
PINGROUP(9, NORTH, blsp_spi3, ddr_bist, NA, NA, NA, wlan1_adc0,
@@ -1441,10 +1511,10 @@ static const struct msm_pingroup msmfalcon_groups[] = {
atest_usb11, bimc_dte1, NA),
PINGROUP(11, NORTH, blsp_spi3, blsp_i2c3, NA, dbg_out, wlan2_adc0,
atest_usb10, bimc_dte0, NA, NA),
- PINGROUP(12, NORTH, blsp_spi4, pri_mi2s, NA, phase_flag26, qdss_cti,
+ PINGROUP(12, NORTH, blsp_spi4, pri_mi2s, NA, phase_flag26, qdss_cti1_b,
NA, NA, NA, NA),
PINGROUP(13, NORTH, blsp_spi4, DP_HOT, pri_mi2s_ws, NA, NA,
- phase_flag27, qdss_cti, NA, NA),
+ phase_flag27, qdss_cti0_b, NA, NA),
PINGROUP(14, NORTH, blsp_spi4, blsp_i2c4, pri_mi2s, NA, phase_flag28,
NA, NA, NA, NA),
PINGROUP(15, NORTH, blsp_spi4, blsp_i2c4, pri_mi2s, NA, NA, NA, NA, NA,
@@ -1457,30 +1527,30 @@ static const struct msm_pingroup msmfalcon_groups[] = {
NA, NA),
PINGROUP(19, CENTER, blsp_uart5, blsp_spi5, blsp_i2c5, NA, NA, NA, NA,
NA, NA),
- PINGROUP(20, SOUTH, blsp_spi6, blsp_uart2, blsp_uim6, NA, NA, NA, NA,
+ PINGROUP(20, SOUTH, NA, NA, blsp_uim6, NA, NA, NA, NA,
NA, NA),
- PINGROUP(21, SOUTH, blsp_spi6, blsp_uart2, blsp_uim6, NA, phase_flag11,
- qdss_cti, vsense_data0, NA, NA),
- PINGROUP(22, CENTER, blsp_spi6, blsp_uart2, blsp_i2c6, NA,
+ PINGROUP(21, SOUTH, NA, NA, blsp_uim6, NA, phase_flag11,
+ qdss_cti0_b, vsense_data0, NA, NA),
+ PINGROUP(22, CENTER, blsp_spi6, NA, blsp_i2c6, NA,
phase_flag12, vsense_data1, NA, NA, NA),
- PINGROUP(23, CENTER, blsp_spi6, blsp_uart2, blsp_i2c6, NA,
+ PINGROUP(23, CENTER, blsp_spi6, NA, blsp_i2c6, NA,
phase_flag13, vsense_mode, NA, NA, NA),
- PINGROUP(24, NORTH, blsp_spi7, BLSP_UART, sec_mi2s, sndwire_clk, NA,
+ PINGROUP(24, NORTH, blsp_spi7, blsp_uart6_a, sec_mi2s, sndwire_clk, NA,
NA, phase_flag17, vsense_clkout, NA),
- PINGROUP(25, NORTH, blsp_spi7, BLSP_UART, sec_mi2s, sndwire_data, NA,
+ PINGROUP(25, NORTH, blsp_spi7, blsp_uart6_a, sec_mi2s, sndwire_data, NA,
NA, phase_flag18, NA, NA),
- PINGROUP(26, NORTH, blsp_spi7, BLSP_UART, blsp_i2c7, sec_mi2s, NA,
+ PINGROUP(26, NORTH, blsp_spi7, blsp_uart6_a, blsp_i2c7, sec_mi2s, NA,
phase_flag19, NA, NA, NA),
- PINGROUP(27, NORTH, blsp_spi7, BLSP_UART, blsp_i2c7, vfr_1, sec_mi2s,
+ PINGROUP(27, NORTH, blsp_spi7, blsp_uart6_a, blsp_i2c7, vfr_1, sec_mi2s,
NA, phase_flag20, NA, NA),
- PINGROUP(28, CENTER, blsp_spi, BLSP_UART, m_voc, NA, phase_flag21, NA,
- NA, NA, NA),
- PINGROUP(29, CENTER, blsp_spi, BLSP_UART, NA, NA, phase_flag22, NA, NA,
- NA, NA),
- PINGROUP(30, CENTER, blsp_spi, BLSP_UART, BLSP_I2C, blsp_spi3, NA,
- phase_flag23, NA, NA, NA),
- PINGROUP(31, CENTER, blsp_spi, BLSP_UART, BLSP_I2C, pwr_modem, NA,
- phase_flag24, qdss_gpio, NA, NA),
+ PINGROUP(28, CENTER, blsp_spi8_a, blsp_uart6_b, m_voc, NA, phase_flag21,
+ NA, NA, NA, NA),
+ PINGROUP(29, CENTER, blsp_spi8_a, blsp_uart6_b, NA, NA, phase_flag22,
+ NA, NA, NA, NA),
+ PINGROUP(30, CENTER, blsp_spi8_a, blsp_uart6_b, blsp_i2c8_a,
+ blsp_spi3_cs1, NA, phase_flag23, NA, NA, NA),
+ PINGROUP(31, CENTER, blsp_spi8_a, blsp_uart6_b, blsp_i2c8_a, pwr_modem,
+ NA, phase_flag24, qdss_gpio, NA, NA),
PINGROUP(32, SOUTH, cam_mclk, pwr_nav, NA, NA, qdss_gpio0, NA, NA, NA,
NA),
PINGROUP(33, SOUTH, cam_mclk, qspi_data0, pwr_crypto, NA, NA,
@@ -1495,30 +1565,35 @@ static const struct msm_pingroup msmfalcon_groups[] = {
atest_usb23, NA, NA, NA),
PINGROUP(38, SOUTH, cci_i2c, NA, NA, qdss_gpio6, NA, NA, NA, NA, NA),
PINGROUP(39, SOUTH, cci_i2c, NA, NA, qdss_gpio7, NA, NA, NA, NA, NA),
- PINGROUP(40, SOUTH, CCI_TIMER0, NA, blsp_spi, NA, NA, NA, NA, NA, NA),
- PINGROUP(41, SOUTH, CCI_TIMER1, NA, blsp_spi, NA, NA, NA, NA, NA, NA),
+ PINGROUP(40, SOUTH, CCI_TIMER0, NA, blsp_spi8_b, NA, NA, NA, NA, NA,
+ NA),
+ PINGROUP(41, SOUTH, CCI_TIMER1, NA, blsp_spi8_b, NA, NA, NA, NA, NA,
+ NA),
PINGROUP(42, SOUTH, mdss_vsync0, mdss_vsync1, mdss_vsync2, mdss_vsync3,
NA, NA, qdss_gpio9, NA, NA),
PINGROUP(43, SOUTH, CCI_TIMER3, CCI_ASYNC, qspi_cs, NA, NA,
qdss_gpio10, NA, NA, NA),
- PINGROUP(44, SOUTH, CCI_TIMER4, CCI_ASYNC, blsp_spi, BLSP_I2C, NA, NA,
- qdss_gpio11, NA, NA),
+ PINGROUP(44, SOUTH, CCI_TIMER4, CCI_ASYNC, blsp_spi8_b, blsp_i2c8_b, NA,
+ NA, qdss_gpio11, NA, NA),
PINGROUP(45, SOUTH, cci_async, NA, NA, qdss_gpio12, NA, NA, NA, NA, NA),
PINGROUP(46, SOUTH, blsp_spi1, NA, NA, qdss_gpio13, NA, NA, NA, NA, NA),
PINGROUP(47, SOUTH, qspi_clk, NA, phase_flag30, qdss_gpio14, NA, NA,
NA, NA, NA),
PINGROUP(48, SOUTH, NA, phase_flag1, qdss_gpio15, NA, NA, NA, NA, NA,
NA),
- PINGROUP(49, SOUTH, NA, phase_flag2, qdss_cti, NA, NA, NA, NA, NA, NA),
- PINGROUP(50, SOUTH, qspi_cs, NA, phase_flag9, qdss_cti, NA, NA, NA, NA,
- NA),
+ PINGROUP(49, SOUTH, blsp_spi6, phase_flag2, qdss_cti0_a, NA, NA, NA,
+ NA, NA, NA),
+ PINGROUP(50, SOUTH, qspi_cs, NA, phase_flag9, qdss_cti0_a, NA, NA, NA,
+ NA, NA),
PINGROUP(51, SOUTH, qspi_data3, NA, phase_flag15, qdss_gpio8, NA, NA,
NA, NA, NA),
- PINGROUP(52, SOUTH, CCI_TIMER2, blsp_spi, BLSP_I2C, NA, phase_flag16,
- qdss_gpio, NA, NA, NA),
- PINGROUP(53, NORTH, NA, phase_flag6, qdss_cti, NA, NA, NA, NA, NA, NA),
+ PINGROUP(52, SOUTH, CCI_TIMER2, blsp_spi8_b, blsp_i2c8_b, blsp_spi6,
+ phase_flag16, qdss_gpio, NA, NA, NA),
+ PINGROUP(53, NORTH, NA, phase_flag6, qdss_cti1_a, NA, NA, NA, NA, NA,
+ NA),
PINGROUP(54, NORTH, NA, NA, phase_flag29, NA, NA, NA, NA, NA, NA),
- PINGROUP(55, SOUTH, NA, phase_flag25, qdss_cti, NA, NA, NA, NA, NA, NA),
+ PINGROUP(55, SOUTH, NA, phase_flag25, qdss_cti1_a, NA, NA, NA, NA, NA,
+ NA),
PINGROUP(56, SOUTH, NA, phase_flag10, qdss_gpio3, NA, atest_usb20, NA,
NA, NA, NA),
PINGROUP(57, SOUTH, gcc_gp1, NA, phase_flag4, atest_usb22, NA, NA, NA,
@@ -1533,11 +1608,11 @@ static const struct msm_pingroup msmfalcon_groups[] = {
PINGROUP(62, NORTH, sec_mi2s, audio_ref, MDP_VSYNC, cri_trng, NA, NA,
atest_char0, NA, NA),
PINGROUP(63, NORTH, NA, NA, NA, qdss_gpio1, NA, NA, NA, NA, NA),
- PINGROUP(64, SOUTH, blsp_spi8, sp_cmu, NA, NA, qdss_gpio2, NA, NA, NA,
- NA),
- PINGROUP(65, SOUTH, NA, NAV_PPS, NAV_PPS, GPS_TX, blsp_spi3, adsp_ext,
- NA, NA, NA),
- PINGROUP(66, NORTH, NA, NA, qdss_cti, NA, NA, NA, NA, NA, NA),
+ PINGROUP(64, SOUTH, blsp_spi8_cs1, sp_cmu, NA, NA, qdss_gpio2, NA, NA,
+ NA, NA),
+ PINGROUP(65, SOUTH, NA, nav_pps_a, nav_pps_a, gps_tx_a, blsp_spi3_cs2,
+ adsp_ext, NA, NA, NA),
+ PINGROUP(66, NORTH, NA, NA, qdss_cti1_b, NA, NA, NA, NA, NA, NA),
PINGROUP(67, NORTH, NA, NA, qdss_gpio0, NA, NA, NA, NA, NA, NA),
PINGROUP(68, NORTH, isense_dbg, NA, phase_flag0, qdss_gpio, NA, NA, NA,
NA, NA),
@@ -1550,12 +1625,13 @@ static const struct msm_pingroup msmfalcon_groups[] = {
PINGROUP(73, NORTH, NA, NA, qdss_gpio15, NA, NA, NA, NA, NA, NA),
PINGROUP(74, NORTH, mdp_vsync, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(75, NORTH, NA, NA, qdss_gpio8, NA, NA, NA, NA, NA, NA),
- PINGROUP(76, NORTH, blsp_spi8, NA, NA, NA, qdss_gpio9, NA, NA, NA, NA),
+ PINGROUP(76, NORTH, blsp_spi8_cs2, NA, NA, NA, qdss_gpio9, NA, NA, NA,
+ NA),
PINGROUP(77, NORTH, NA, NA, qdss_gpio10, NA, NA, NA, NA, NA, NA),
PINGROUP(78, NORTH, gcc_gp1, NA, qdss_gpio13, NA, NA, NA, NA, NA, NA),
PINGROUP(79, SOUTH, NA, NA, qdss_gpio11, NA, NA, NA, NA, NA, NA),
- PINGROUP(80, SOUTH, NAV_PPS, NAV_PPS, GPS_TX, NA, NA, qdss_gpio12, NA,
- NA, NA),
+ PINGROUP(80, SOUTH, nav_pps_b, nav_pps_b, gps_tx_c, NA, NA, qdss_gpio12,
+ NA, NA, NA),
PINGROUP(81, CENTER, mss_lte, gcc_gp2, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(82, CENTER, mss_lte, gcc_gp3, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(83, SOUTH, uim2_data, NA, NA, NA, NA, NA, NA, NA, NA),
@@ -1573,8 +1649,8 @@ static const struct msm_pingroup msmfalcon_groups[] = {
PINGROUP(95, SOUTH, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(96, SOUTH, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(97, SOUTH, NA, ldo_en, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(98, SOUTH, NA, NAV_PPS, NAV_PPS, GPS_TX, ldo_update, NA, NA,
- NA, NA),
+ PINGROUP(98, SOUTH, NA, nav_pps_c, nav_pps_c, gps_tx_b, ldo_update, NA,
+ NA, NA, NA),
PINGROUP(99, SOUTH, qlink_request, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(100, SOUTH, qlink_enable, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(101, SOUTH, NA, NA, NA, NA, NA, NA, NA, NA, NA),
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa.c b/drivers/platform/msm/ipa/ipa_v2/ipa.c
index 804c89dc9533..73add50cf224 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa.c
@@ -4907,20 +4907,16 @@ int ipa_iommu_map(struct iommu_domain *domain,
IPADBG("domain =0x%p iova 0x%lx\n", domain, iova);
IPADBG("paddr =0x%pa size 0x%x\n", &paddr, (u32)size);
- /* make sure no overlapping */
+ /* Checking the address overlapping */
if (domain == ipa2_get_smmu_domain()) {
if (iova >= ap_cb->va_start && iova < ap_cb->va_end) {
IPAERR("iommu AP overlap addr 0x%lx\n", iova);
- ipa_assert();
- return -EFAULT;
}
} else if (domain == ipa2_get_wlan_smmu_domain()) {
/* wlan is one time map */
} else if (domain == ipa2_get_uc_smmu_domain()) {
if (iova >= uc_cb->va_start && iova < uc_cb->va_end) {
IPAERR("iommu uC overlap addr 0x%lx\n", iova);
- ipa_assert();
- return -EFAULT;
}
} else {
IPAERR("Unexpected domain 0x%p\n", domain);
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c
index 7e15bcfc84ff..d51e9ac97fe0 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c
@@ -18,6 +18,7 @@
#include "ipa_i.h"
#include "ipa_trace.h"
+#define IPA_WAN_AGGR_PKT_CNT 5
#define IPA_LAST_DESC_CNT 0xFFFF
#define POLLING_INACTIVITY_RX 40
#define POLLING_INACTIVITY_TX 40
@@ -1099,16 +1100,18 @@ int ipa2_rx_poll(u32 clnt_hdl, int weight)
break;
ipa_wq_rx_common(ep->sys, iov.size);
- cnt += 5;
+ cnt += IPA_WAN_AGGR_PKT_CNT;
};
- if (cnt == 0) {
+ if (cnt == 0 || cnt < weight) {
ep->inactive_cycles++;
ep->client_notify(ep->priv, IPA_CLIENT_COMP_NAPI, 0);
if (ep->inactive_cycles > 3 || ep->sys->len == 0) {
ep->switch_to_intr = true;
delay = 0;
+ } else if (cnt < weight) {
+ delay = 0;
}
queue_delayed_work(ep->sys->wq,
&ep->sys->switch_to_intr_work, msecs_to_jiffies(delay));
@@ -3168,14 +3171,9 @@ static int ipa_assign_policy_v2(struct ipa_sys_connect_params *in,
sys->repl_hdlr =
ipa_replenish_rx_cache;
}
- if (in->napi_enabled) {
- sys->rx_pool_sz =
- IPA_WAN_NAPI_CONS_RX_POOL_SZ;
- if (in->recycle_enabled) {
- sys->repl_hdlr =
- ipa_replenish_rx_cache_recycle;
- }
- }
+ if (in->napi_enabled && in->recycle_enabled)
+ sys->repl_hdlr =
+ ipa_replenish_rx_cache_recycle;
sys->ep->wakelock_client =
IPA_WAKELOCK_REF_CLIENT_WAN_RX;
in->ipa_ep_cfg.aggr.aggr_sw_eof_active
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h
index 73206abf9cfd..866170d3324d 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h
@@ -51,8 +51,6 @@
#define IPA_UC_FINISH_MAX 6
#define IPA_UC_WAIT_MIN_SLEEP 1000
#define IPA_UC_WAII_MAX_SLEEP 1200
-#define IPA_WAN_NAPI_CONS_RX_POOL_SZ (IPA_GENERIC_RX_POOL_SZ*3)
-#define IPA_WAN_CONS_DESC_FIFO_SZ (IPA_SYS_DESC_FIFO_SZ*3)
#define IPA_MAX_STATUS_STAT_NUM 30
diff --git a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
index 520f139ee38a..c2e43a62ab69 100644
--- a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
@@ -62,6 +62,7 @@
#define IPA_UEVENT_NUM_EVNP 4 /* number of event pointers */
#define NAPI_WEIGHT 60
+#define IPA_WWAN_CONS_DESC_FIFO_SZ 1024
static struct net_device *ipa_netdevs[IPA_WWAN_DEVICE_COUNT];
static struct ipa_sys_connect_params apps_to_ipa_ep_cfg, ipa_to_apps_ep_cfg;
@@ -100,6 +101,7 @@ struct ipa_rmnet_plat_drv_res {
bool ipa_loaduC;
bool ipa_advertise_sg_support;
bool ipa_napi_enable;
+ u32 wan_rx_desc_size;
};
static struct ipa_rmnet_plat_drv_res ipa_rmnet_res;
@@ -1291,10 +1293,8 @@ static int handle_ingress_format(struct net_device *dev,
ipa_to_apps_ep_cfg.priv = dev;
ipa_to_apps_ep_cfg.napi_enabled = ipa_rmnet_res.ipa_napi_enable;
- if (ipa_to_apps_ep_cfg.napi_enabled)
- ipa_to_apps_ep_cfg.desc_fifo_sz = IPA_WAN_CONS_DESC_FIFO_SZ;
- else
- ipa_to_apps_ep_cfg.desc_fifo_sz = IPA_SYS_DESC_FIFO_SZ;
+ ipa_to_apps_ep_cfg.desc_fifo_sz =
+ ipa_rmnet_res.wan_rx_desc_size * sizeof(struct sps_iovec);
mutex_lock(&ipa_to_apps_pipe_handle_guard);
if (atomic_read(&is_ssr)) {
@@ -1925,6 +1925,9 @@ static struct notifier_block ssr_notifier = {
static int get_ipa_rmnet_dts_configuration(struct platform_device *pdev,
struct ipa_rmnet_plat_drv_res *ipa_rmnet_drv_res)
{
+ int result;
+
+ ipa_rmnet_drv_res->wan_rx_desc_size = IPA_WWAN_CONS_DESC_FIFO_SZ;
ipa_rmnet_drv_res->ipa_rmnet_ssr =
of_property_read_bool(pdev->dev.of_node,
"qcom,rmnet-ipa-ssr");
@@ -1947,6 +1950,18 @@ static int get_ipa_rmnet_dts_configuration(struct platform_device *pdev,
"qcom,ipa-napi-enable");
pr_info("IPA Napi Enable = %s\n",
ipa_rmnet_drv_res->ipa_napi_enable ? "True" : "False");
+
+ /* Get IPA WAN RX desc fifo size */
+ result = of_property_read_u32(pdev->dev.of_node,
+ "qcom,wan-rx-desc-size",
+ &ipa_rmnet_drv_res->wan_rx_desc_size);
+ if (result)
+ pr_info("using default for wan-rx-desc-size = %u\n",
+ ipa_rmnet_drv_res->wan_rx_desc_size);
+ else
+ IPAWANDBG(": found ipa_drv_res->wan-rx-desc-size = %u\n",
+ ipa_rmnet_drv_res->wan_rx_desc_size);
+
return 0;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index cc1cb456ab8a..be2946c873b3 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -21,6 +21,7 @@
#include "ipahal/ipahal.h"
#include "ipahal/ipahal_fltrt.h"
+#define IPA_WAN_AGGR_PKT_CNT 5
#define IPA_LAST_DESC_CNT 0xFFFF
#define POLLING_INACTIVITY_RX 40
#define POLLING_MIN_SLEEP_RX 1010
@@ -60,7 +61,6 @@
#define IPA_ODU_RX_POOL_SZ 64
#define IPA_SIZE_DL_CSUM_META_TRAILER 8
-#define IPA_GSI_EVT_RING_LEN 4096
#define IPA_GSI_MAX_CH_LOW_WEIGHT 15
#define IPA_GSI_EVT_RING_INT_MODT 3200 /* 0.1s under 32KHz clock */
@@ -1723,6 +1723,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
struct ipa3_sys_context *sys;
int src_ep_idx;
int num_frags, f;
+ struct ipa_gsi_ep_config *gsi_ep;
if (unlikely(!ipa3_ctx)) {
IPAERR("IPA3 driver was not initialized\n");
@@ -1734,23 +1735,6 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
return -EINVAL;
}
- num_frags = skb_shinfo(skb)->nr_frags;
- if (num_frags) {
- /* 1 desc for tag to resolve status out-of-order issue;
- * 1 desc is needed for the linear portion of skb;
- * 1 desc may be needed for the PACKET_INIT;
- * 1 desc for each frag
- */
- desc = kzalloc(sizeof(*desc) * (num_frags + 3), GFP_ATOMIC);
- if (!desc) {
- IPAERR("failed to alloc desc array\n");
- goto fail_mem;
- }
- } else {
- memset(_desc, 0, 3 * sizeof(struct ipa3_desc));
- desc = &_desc[0];
- }
-
/*
* USB_CONS: PKT_INIT ep_idx = dst pipe
* Q6_CONS: PKT_INIT ep_idx = sender pipe
@@ -1787,6 +1771,37 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
goto fail_gen;
}
+ num_frags = skb_shinfo(skb)->nr_frags;
+ /*
+ * make sure TLV FIFO supports the needed frags.
+ * 2 descriptors are needed for IP_PACKET_INIT and TAG_STATUS.
+ * 1 descriptor needed for the linear portion of skb.
+ */
+ gsi_ep = ipa3_get_gsi_ep_info(src_ep_idx);
+ if (gsi_ep && (num_frags + 3 > gsi_ep->ipa_if_tlv)) {
+ if (skb_linearize(skb)) {
+ IPAERR("Failed to linear skb with %d frags\n",
+ num_frags);
+ goto fail_gen;
+ }
+ num_frags = 0;
+ }
+ if (num_frags) {
+ /* 1 desc for tag to resolve status out-of-order issue;
+ * 1 desc is needed for the linear portion of skb;
+ * 1 desc may be needed for the PACKET_INIT;
+ * 1 desc for each frag
+ */
+ desc = kzalloc(sizeof(*desc) * (num_frags + 3), GFP_ATOMIC);
+ if (!desc) {
+ IPAERR("failed to alloc desc array\n");
+ goto fail_gen;
+ }
+ } else {
+ memset(_desc, 0, 3 * sizeof(struct ipa3_desc));
+ desc = &_desc[0];
+ }
+
if (dst_ep_idx != -1) {
/* SW data path */
cmd.destination_pipe_index = dst_ep_idx;
@@ -1794,7 +1809,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
IPA_IMM_CMD_IP_PACKET_INIT, &cmd, true);
if (unlikely(!cmd_pyld)) {
IPAERR("failed to construct ip_packet_init imm cmd\n");
- goto fail_gen;
+ goto fail_mem;
}
/* the tag field will be populated in ipa3_send() function */
@@ -1863,7 +1878,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
if (num_frags == 0) {
if (ipa3_send(sys, 2, desc, true)) {
IPAERR("fail to send skb %p HWP\n", skb);
- goto fail_gen;
+ goto fail_mem;
}
} else {
for (f = 0; f < num_frags; f++) {
@@ -1880,7 +1895,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
if (ipa3_send(sys, num_frags + 2, desc, true)) {
IPAERR("fail to send skb %p num_frags %u HWP\n",
skb, num_frags);
- goto fail_gen;
+ goto fail_mem;
}
}
IPA_STATS_INC_CNT(ipa3_ctx->stats.tx_hw_pkts);
@@ -1894,10 +1909,10 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
fail_send:
ipahal_destroy_imm_cmd(cmd_pyld);
-fail_gen:
+fail_mem:
if (num_frags)
kfree(desc);
-fail_mem:
+fail_gen:
return -EFAULT;
}
@@ -3298,9 +3313,6 @@ static int ipa3_assign_policy(struct ipa_sys_connect_params *in,
sys->repl_hdlr =
ipa3_replenish_rx_cache;
}
- if (in->napi_enabled)
- sys->rx_pool_sz =
- IPA_WAN_NAPI_CONS_RX_POOL_SZ;
if (in->napi_enabled && in->recycle_enabled)
sys->repl_hdlr =
ipa3_replenish_rx_cache_recycle;
@@ -3965,13 +3977,19 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in,
gsi_evt_ring_props.re_size =
GSI_EVT_RING_RE_SIZE_16B;
- gsi_evt_ring_props.ring_len = IPA_GSI_EVT_RING_LEN;
+ /*
+ * GSI ring length is calculated based on the desc_fifo_sz
+ * which was meant to define the BAM desc fifo. GSI descriptors
+ * are 16B as opposed to 8B for BAM.
+ */
+ gsi_evt_ring_props.ring_len = 2 * in->desc_fifo_sz;
+
gsi_evt_ring_props.ring_base_vaddr =
- dma_alloc_coherent(ipa3_ctx->pdev, IPA_GSI_EVT_RING_LEN,
- &evt_dma_addr, GFP_KERNEL);
+ dma_alloc_coherent(ipa3_ctx->pdev,
+ gsi_evt_ring_props.ring_len, &evt_dma_addr, GFP_KERNEL);
if (!gsi_evt_ring_props.ring_base_vaddr) {
IPAERR("fail to dma alloc %u bytes\n",
- IPA_GSI_EVT_RING_LEN);
+ gsi_evt_ring_props.ring_len);
return -ENOMEM;
}
gsi_evt_ring_props.ring_base_addr = evt_dma_addr;
@@ -4098,7 +4116,7 @@ fail_get_gsi_ep_info:
}
fail_alloc_evt_ring:
if (gsi_evt_ring_props.ring_base_vaddr)
- dma_free_coherent(ipa3_ctx->pdev, IPA_GSI_EVT_RING_LEN,
+ dma_free_coherent(ipa3_ctx->pdev, gsi_evt_ring_props.ring_len,
gsi_evt_ring_props.ring_base_vaddr, evt_dma_addr);
IPAERR("Return with err: %d\n", result);
return result;
@@ -4280,16 +4298,18 @@ int ipa3_rx_poll(u32 clnt_hdl, int weight)
break;
ipa3_wq_rx_common(ep->sys, mem_info.size);
- cnt += 5;
+ cnt += IPA_WAN_AGGR_PKT_CNT;
};
- if (cnt == 0) {
+ if (cnt == 0 || cnt < weight) {
ep->inactive_cycles++;
ep->client_notify(ep->priv, IPA_CLIENT_COMP_NAPI, 0);
if (ep->inactive_cycles > 3 || ep->sys->len == 0) {
ep->switch_to_intr = true;
delay = 0;
+ } else if (cnt < weight) {
+ delay = 0;
}
queue_delayed_work(ep->sys->wq,
&ep->sys->switch_to_intr_work, msecs_to_jiffies(delay));
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index 40f1e93653f9..1b78835cda6b 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -53,8 +53,6 @@
#define IPA_UC_FINISH_MAX 6
#define IPA_UC_WAIT_MIN_SLEEP 1000
#define IPA_UC_WAII_MAX_SLEEP 1200
-#define IPA_WAN_NAPI_CONS_RX_POOL_SZ (IPA_GENERIC_RX_POOL_SZ*3)
-#define IPA_WAN_CONS_DESC_FIFO_SZ (IPA_SYS_DESC_FIFO_SZ*3)
#define IPA_MAX_STATUS_STAT_NUM 30
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c
index cb47773e8a39..21ce28204069 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c
@@ -585,7 +585,9 @@ send_cmd:
if (ipa3_ctx->uc_ctx.uc_status != expected_status) {
if (ipa3_ctx->uc_ctx.uc_status ==
- IPA_HW_PROD_DISABLE_CMD_GSI_STOP_FAILURE) {
+ IPA_HW_PROD_DISABLE_CMD_GSI_STOP_FAILURE ||
+ ipa3_ctx->uc_ctx.uc_status ==
+ IPA_HW_CONS_DISABLE_CMD_GSI_STOP_FAILURE) {
retries++;
if (retries == IPA_GSI_CHANNEL_STOP_MAX_RETRY) {
IPAERR("Failed after %d tries\n", retries);
@@ -594,7 +596,9 @@ send_cmd:
return -EFAULT;
}
IPA3_UC_UNLOCK(flags);
- ipa3_inject_dma_task_for_gsi();
+ if (ipa3_ctx->uc_ctx.uc_status ==
+ IPA_HW_PROD_DISABLE_CMD_GSI_STOP_FAILURE)
+ ipa3_inject_dma_task_for_gsi();
/* sleep for short period to flush IPA */
usleep_range(IPA_GSI_CHANNEL_STOP_SLEEP_MIN_USEC,
IPA_GSI_CHANNEL_STOP_SLEEP_MAX_USEC);
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
index 8f6c303d2867..0419249890e9 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
@@ -65,6 +65,7 @@
((rmnet_ipa3_ctx && rmnet_ipa3_ctx->wwan_priv) ? \
rmnet_ipa3_ctx->wwan_priv->net : NULL)
+#define IPA_WWAN_CONS_DESC_FIFO_SZ 256
static int ipa3_wwan_add_ul_flt_rule_to_ipa(void);
static int ipa3_wwan_del_ul_flt_rule_to_ipa(void);
@@ -89,6 +90,7 @@ struct ipa3_rmnet_plat_drv_res {
bool ipa_loaduC;
bool ipa_advertise_sg_support;
bool ipa_napi_enable;
+ u32 wan_rx_desc_size;
};
/**
@@ -1275,7 +1277,7 @@ static int handle3_ingress_format(struct net_device *dev,
ipa_wan_ep_cfg->ipa_ep_cfg.aggr.aggr_pkt_limit =
in->u.ingress_format.agg_count;
- if (ipa_wan_ep_cfg->napi_enabled) {
+ if (ipa3_rmnet_res.ipa_napi_enable) {
ipa_wan_ep_cfg->recycle_enabled = true;
ep_cfg = (struct rmnet_phys_ep_conf_s *)
rcu_dereference(dev->rx_handler_data);
@@ -1303,10 +1305,8 @@ static int handle3_ingress_format(struct net_device *dev,
ipa_wan_ep_cfg->priv = dev;
ipa_wan_ep_cfg->napi_enabled = ipa3_rmnet_res.ipa_napi_enable;
- if (ipa_wan_ep_cfg->napi_enabled)
- ipa_wan_ep_cfg->desc_fifo_sz = IPA_WAN_CONS_DESC_FIFO_SZ;
- else
- ipa_wan_ep_cfg->desc_fifo_sz = IPA_SYS_DESC_FIFO_SZ;
+ ipa_wan_ep_cfg->desc_fifo_sz =
+ ipa3_rmnet_res.wan_rx_desc_size * sizeof(struct sps_iovec);
mutex_lock(&rmnet_ipa3_ctx->ipa_to_apps_pipe_handle_guard);
@@ -1957,6 +1957,9 @@ static struct notifier_block ipa3_ssr_notifier = {
static int get_ipa_rmnet_dts_configuration(struct platform_device *pdev,
struct ipa3_rmnet_plat_drv_res *ipa_rmnet_drv_res)
{
+ int result;
+
+ ipa_rmnet_drv_res->wan_rx_desc_size = IPA_WWAN_CONS_DESC_FIFO_SZ;
ipa_rmnet_drv_res->ipa_rmnet_ssr =
of_property_read_bool(pdev->dev.of_node,
"qcom,rmnet-ipa-ssr");
@@ -1979,6 +1982,18 @@ static int get_ipa_rmnet_dts_configuration(struct platform_device *pdev,
"qcom,ipa-napi-enable");
pr_info("IPA Napi Enable = %s\n",
ipa_rmnet_drv_res->ipa_napi_enable ? "True" : "False");
+
+ /* Get IPA WAN RX desc fifo size */
+ result = of_property_read_u32(pdev->dev.of_node,
+ "qcom,wan-rx-desc-size",
+ &ipa_rmnet_drv_res->wan_rx_desc_size);
+ if (result)
+ pr_info("using default for wan-rx-desc-size = %u\n",
+ ipa_rmnet_drv_res->wan_rx_desc_size);
+ else
+ IPAWANDBG(": found ipa_drv_res->wan-rx-desc-size = %u\n",
+ ipa_rmnet_drv_res->wan_rx_desc_size);
+
return 0;
}
diff --git a/drivers/platform/msm/msm_11ad/msm_11ad.c b/drivers/platform/msm/msm_11ad/msm_11ad.c
index 45fedfa72bda..5810f7bf7f2f 100644
--- a/drivers/platform/msm/msm_11ad/msm_11ad.c
+++ b/drivers/platform/msm/msm_11ad/msm_11ad.c
@@ -51,6 +51,9 @@
#define VDDIO_MAX_UV 2040000
#define VDDIO_MAX_UA 70300
+#define DISABLE_PCIE_L1_MASK 0xFFFFFFFD
+#define PCIE20_CAP_LINKCTRLSTATUS 0x80
+
struct device;
static const char * const gpio_en_name = "qcom,wigig-en";
@@ -505,6 +508,7 @@ static int ops_resume(void *handle)
int rc;
struct msm11ad_ctx *ctx = handle;
struct pci_dev *pcidev;
+ u32 val;
pr_info("%s(%p)\n", __func__, handle);
if (!ctx) {
@@ -548,6 +552,27 @@ static int ops_resume(void *handle)
goto err_suspend_rc;
}
+ /* Disable L1 */
+ rc = pci_read_config_dword(ctx->pcidev,
+ PCIE20_CAP_LINKCTRLSTATUS, &val);
+ if (rc) {
+ dev_err(ctx->dev,
+ "reading PCIE20_CAP_LINKCTRLSTATUS failed:%d\n",
+ rc);
+ goto err_suspend_rc;
+ }
+ val &= DISABLE_PCIE_L1_MASK; /* disable bit 1 */
+ dev_dbg(ctx->dev, "writing PCIE20_CAP_LINKCTRLSTATUS (val 0x%x)\n",
+ val);
+ rc = pci_write_config_dword(ctx->pcidev,
+ PCIE20_CAP_LINKCTRLSTATUS, val);
+ if (rc) {
+ dev_err(ctx->dev,
+ "writing PCIE20_CAP_LINKCTRLSTATUS (val 0x%x) failed:%d\n",
+ val, rc);
+ goto err_suspend_rc;
+ }
+
return 0;
err_suspend_rc:
@@ -792,6 +817,7 @@ static int msm_11ad_probe(struct platform_device *pdev)
struct device_node *rc_node;
struct pci_dev *pcidev = NULL;
int rc;
+ u32 val;
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
@@ -907,6 +933,28 @@ static int msm_11ad_probe(struct platform_device *pdev)
goto out_rc;
}
ctx->pcidev = pcidev;
+
+ /* Disable L1 */
+ rc = pci_read_config_dword(ctx->pcidev,
+ PCIE20_CAP_LINKCTRLSTATUS, &val);
+ if (rc) {
+ dev_err(ctx->dev,
+ "reading PCIE20_CAP_LINKCTRLSTATUS failed:%d\n",
+ rc);
+ goto out_rc;
+ }
+ val &= DISABLE_PCIE_L1_MASK; /* disable bit 1 */
+ dev_dbg(ctx->dev, "writing PCIE20_CAP_LINKCTRLSTATUS (val 0x%x)\n",
+ val);
+ rc = pci_write_config_dword(ctx->pcidev,
+ PCIE20_CAP_LINKCTRLSTATUS, val);
+ if (rc) {
+ dev_err(ctx->dev,
+ "writing PCIE20_CAP_LINKCTRLSTATUS (val 0x%x) failed:%d\n",
+ val, rc);
+ goto out_rc;
+ }
+
rc = pci_save_state(pcidev);
if (rc) {
dev_err(ctx->dev, "pci_save_state failed :%d\n", rc);
diff --git a/drivers/power/qcom-charger/fg-core.h b/drivers/power/qcom-charger/fg-core.h
index 3f8f66f1f7d8..d612016b1b79 100644
--- a/drivers/power/qcom-charger/fg-core.h
+++ b/drivers/power/qcom-charger/fg-core.h
@@ -74,6 +74,7 @@ enum fg_debug_flag {
FG_BUS_WRITE = BIT(5), /* Show REGMAP writes */
FG_BUS_READ = BIT(6), /* Show REGMAP reads */
FG_CAP_LEARN = BIT(7), /* Show capacity learning */
+ FG_TTF = BIT(8), /* Show time to full */
};
/* SRAM access */
@@ -128,6 +129,7 @@ enum {
*/
enum fg_sram_param_id {
FG_SRAM_BATT_SOC = 0,
+ FG_SRAM_FULL_SOC,
FG_SRAM_VOLTAGE_PRED,
FG_SRAM_OCV,
FG_SRAM_RSLOW,
@@ -250,6 +252,29 @@ struct fg_irq_info {
int irq;
};
+struct fg_circ_buf {
+ int arr[20];
+ int size;
+ int head;
+};
+
+struct fg_pt {
+ s32 x;
+ s32 y;
+};
+
+static const struct fg_pt fg_ln_table[] = {
+ { 1000, 0 },
+ { 2000, 693 },
+ { 4000, 1386 },
+ { 6000, 1792 },
+ { 8000, 2079 },
+ { 16000, 2773 },
+ { 32000, 3466 },
+ { 64000, 4159 },
+ { 128000, 4852 },
+};
+
struct fg_chip {
struct device *dev;
struct pmic_revid_data *pmic_rev_id;
@@ -275,12 +300,15 @@ struct fg_chip {
struct fg_cap_learning cl;
struct mutex bus_lock;
struct mutex sram_rw_lock;
+ struct mutex batt_avg_lock;
u32 batt_soc_base;
u32 batt_info_base;
u32 mem_if_base;
int batt_id_kohms;
- int status;
+ int charge_status;
+ int prev_charge_status;
int charge_done;
+ int charge_type;
int last_soc;
int last_batt_temp;
int health;
@@ -289,7 +317,6 @@ struct fg_chip {
bool battery_missing;
bool fg_restarting;
bool charge_full;
- bool charge_empty;
bool recharge_soc_adjusted;
bool ki_coeff_dischg_en;
bool esr_fcc_ctrl_en;
@@ -298,6 +325,9 @@ struct fg_chip {
struct delayed_work profile_load_work;
struct work_struct status_change_work;
struct work_struct cycle_count_work;
+ struct delayed_work batt_avg_work;
+ struct fg_circ_buf ibatt_circ_buf;
+ struct fg_circ_buf vbatt_circ_buf;
};
/* Debugfs data structures are below */
@@ -342,9 +372,15 @@ extern int fg_read(struct fg_chip *chip, int addr, u8 *val, int len);
extern int fg_write(struct fg_chip *chip, int addr, u8 *val, int len);
extern int fg_masked_write(struct fg_chip *chip, int addr, u8 mask, u8 val);
extern int fg_ima_init(struct fg_chip *chip);
+extern int fg_clear_ima_errors_if_any(struct fg_chip *chip, bool check_hw_sts);
+extern int fg_clear_dma_errors_if_any(struct fg_chip *chip);
extern int fg_debugfs_create(struct fg_chip *chip);
extern void fill_string(char *str, size_t str_len, u8 *buf, int buf_len);
extern int64_t twos_compliment_extend(int64_t val, int s_bit_pos);
extern s64 fg_float_decode(u16 val);
extern bool is_input_present(struct fg_chip *chip);
+extern void fg_circ_buf_add(struct fg_circ_buf *, int);
+extern void fg_circ_buf_clr(struct fg_circ_buf *);
+extern int fg_circ_buf_avg(struct fg_circ_buf *, int *);
+extern int fg_lerp(const struct fg_pt *, size_t, s32, s32 *);
#endif
diff --git a/drivers/power/qcom-charger/fg-memif.c b/drivers/power/qcom-charger/fg-memif.c
index c271b24adfc4..a98ff7d765e3 100644
--- a/drivers/power/qcom-charger/fg-memif.c
+++ b/drivers/power/qcom-charger/fg-memif.c
@@ -64,44 +64,90 @@ static int fg_config_access_mode(struct fg_chip *chip, bool access, bool burst)
static int fg_run_iacs_clear_sequence(struct fg_chip *chip)
{
- u8 tmp;
- int rc;
+ u8 val, hw_sts, exp_sts;
+ int rc, tries = 250;
/*
* Values to write for running IACS clear sequence comes from
* hardware documentation.
*/
- rc = fg_masked_write(chip, MEM_IF_IMA_CFG(chip), IACS_CLR_BIT,
- IACS_CLR_BIT);
+ rc = fg_masked_write(chip, MEM_IF_IMA_CFG(chip),
+ IACS_CLR_BIT | STATIC_CLK_EN_BIT,
+ IACS_CLR_BIT | STATIC_CLK_EN_BIT);
if (rc < 0) {
pr_err("failed to write 0x%04x, rc=%d\n", MEM_IF_IMA_CFG(chip),
rc);
return rc;
}
- tmp = 0x4;
- rc = fg_write(chip, MEM_IF_ADDR_MSB(chip), &tmp, 1);
+ rc = fg_config_access_mode(chip, FG_READ, false);
if (rc < 0) {
- pr_err("failed to write 0x%04x, rc=%d\n", MEM_IF_ADDR_LSB(chip),
- rc);
+ pr_err("failed to write to 0x%04x, rc=%d\n",
+ MEM_IF_IMA_CTL(chip), rc);
return rc;
}
- tmp = 0x0;
- rc = fg_write(chip, MEM_IF_WR_DATA3(chip), &tmp, 1);
+ rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
+ MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT,
+ MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT);
if (rc < 0) {
- pr_err("failed to write 0x%04x, rc=%d\n", MEM_IF_WR_DATA3(chip),
- rc);
+ pr_err("failed to set ima_req_access bit rc=%d\n", rc);
return rc;
}
- rc = fg_read(chip, MEM_IF_RD_DATA3(chip), &tmp, 1);
- if (rc < 0) {
- pr_err("failed to read 0x%04x, rc=%d\n", MEM_IF_RD_DATA3(chip),
- rc);
- return rc;
+ /* Delay for the clock to reach FG */
+ usleep_range(35, 40);
+
+ while (1) {
+ val = 0;
+ rc = fg_write(chip, MEM_IF_ADDR_MSB(chip), &val, 1);
+ if (rc < 0) {
+ pr_err("failed to write 0x%04x, rc=%d\n",
+ MEM_IF_ADDR_MSB(chip), rc);
+ return rc;
+ }
+
+ val = 0;
+ rc = fg_write(chip, MEM_IF_WR_DATA3(chip), &val, 1);
+ if (rc < 0) {
+ pr_err("failed to write 0x%04x, rc=%d\n",
+ MEM_IF_WR_DATA3(chip), rc);
+ return rc;
+ }
+
+ rc = fg_read(chip, MEM_IF_RD_DATA3(chip), &val, 1);
+ if (rc < 0) {
+ pr_err("failed to read 0x%04x, rc=%d\n",
+ MEM_IF_RD_DATA3(chip), rc);
+ return rc;
+ }
+
+ /* Delay for IMA hardware to clear */
+ usleep_range(35, 40);
+
+ rc = fg_read(chip, MEM_IF_IMA_HW_STS(chip), &hw_sts, 1);
+ if (rc < 0) {
+ pr_err("failed to read ima_hw_sts rc=%d\n", rc);
+ return rc;
+ }
+
+ if (hw_sts != 0)
+ continue;
+
+ rc = fg_read(chip, MEM_IF_IMA_EXP_STS(chip), &exp_sts, 1);
+ if (rc < 0) {
+ pr_err("failed to read ima_exp_sts rc=%d\n", rc);
+ return rc;
+ }
+
+ if (exp_sts == 0 || !(--tries))
+ break;
}
+ if (!tries)
+ pr_err("Failed to clear the error? hw_sts: %x exp_sts: %d\n",
+ hw_sts, exp_sts);
+
rc = fg_masked_write(chip, MEM_IF_IMA_CFG(chip), IACS_CLR_BIT, 0);
if (rc < 0) {
pr_err("failed to write 0x%04x, rc=%d\n", MEM_IF_IMA_CFG(chip),
@@ -109,14 +155,65 @@ static int fg_run_iacs_clear_sequence(struct fg_chip *chip)
return rc;
}
+ udelay(5);
+
+ rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
+ MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0);
+ if (rc < 0) {
+ pr_err("failed to write to 0x%04x, rc=%d\n",
+ MEM_IF_MEM_INTF_CFG(chip), rc);
+ return rc;
+ }
+
+ /* Delay before next transaction is attempted */
+ usleep_range(35, 40);
fg_dbg(chip, FG_SRAM_READ | FG_SRAM_WRITE, "IACS clear sequence complete\n");
return rc;
}
-static int fg_check_for_ima_errors(struct fg_chip *chip)
+int fg_clear_dma_errors_if_any(struct fg_chip *chip)
+{
+ int rc;
+ u8 dma_sts;
+
+ rc = fg_read(chip, MEM_IF_DMA_STS(chip), &dma_sts, 1);
+ if (rc < 0) {
+ pr_err("failed to read addr=0x%04x, rc=%d\n",
+ MEM_IF_DMA_STS(chip), rc);
+ return rc;
+ }
+ fg_dbg(chip, FG_STATUS, "dma_sts: %x\n", dma_sts);
+
+ if (dma_sts & (DMA_WRITE_ERROR_BIT | DMA_READ_ERROR_BIT)) {
+ rc = fg_masked_write(chip, MEM_IF_DMA_CTL(chip),
+ DMA_CLEAR_LOG_BIT, DMA_CLEAR_LOG_BIT);
+ if (rc < 0) {
+ pr_err("failed to write addr=0x%04x, rc=%d\n",
+ MEM_IF_DMA_CTL(chip), rc);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+int fg_clear_ima_errors_if_any(struct fg_chip *chip, bool check_hw_sts)
{
int rc = 0;
u8 err_sts, exp_sts = 0, hw_sts = 0;
+ bool run_err_clr_seq = false;
+
+ rc = fg_read(chip, MEM_IF_IMA_EXP_STS(chip), &exp_sts, 1);
+ if (rc < 0) {
+ pr_err("failed to read ima_exp_sts rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = fg_read(chip, MEM_IF_IMA_HW_STS(chip), &hw_sts, 1);
+ if (rc < 0) {
+ pr_err("failed to read ima_hw_sts rc=%d\n", rc);
+ return rc;
+ }
rc = fg_read(chip, MEM_IF_IMA_ERR_STS(chip), &err_sts, 1);
if (rc < 0) {
@@ -124,22 +221,30 @@ static int fg_check_for_ima_errors(struct fg_chip *chip)
return rc;
}
- if (err_sts & (ADDR_STBL_ERR_BIT | WR_ACS_ERR_BIT | RD_ACS_ERR_BIT)) {
- rc = fg_read(chip, MEM_IF_IMA_EXP_STS(chip), &exp_sts, 1);
- if (rc < 0) {
- pr_err("failed to read ima_exp_sts rc=%d\n", rc);
- return rc;
- }
+ fg_dbg(chip, FG_SRAM_READ | FG_SRAM_WRITE, "ima_err_sts=%x ima_exp_sts=%x ima_hw_sts=%x\n",
+ err_sts, exp_sts, hw_sts);
- rc = fg_read(chip, MEM_IF_IMA_HW_STS(chip), &hw_sts, 1);
- if (rc < 0) {
- pr_err("failed to read ima_hw_sts rc=%d\n", rc);
- return rc;
+ if (check_hw_sts) {
+ /*
+ * Lower nibble should be equal to upper nibble before SRAM
+ * transactions begins from SW side. If they are unequal, then
+ * the error clear sequence should be run irrespective of IMA
+ * exception errors.
+ */
+ if ((hw_sts & 0x0F) != hw_sts >> 4) {
+ pr_err("IMA HW not in correct state, hw_sts=%x\n",
+ hw_sts);
+ run_err_clr_seq = true;
}
+ }
- pr_err("ima_err_sts=%x ima_exp_sts=%x ima_hw_sts=%x\n",
- err_sts, exp_sts, hw_sts);
+ if (exp_sts & (IACS_ERR_BIT | XCT_TYPE_ERR_BIT | DATA_RD_ERR_BIT |
+ DATA_WR_ERR_BIT | ADDR_BURST_WRAP_BIT | ADDR_STABLE_ERR_BIT)) {
+ pr_err("IMA exception bit set, exp_sts=%x\n", exp_sts);
+ run_err_clr_seq = true;
+ }
+ if (run_err_clr_seq) {
/* clear the error */
rc = fg_run_iacs_clear_sequence(chip);
if (rc < 0) {
@@ -156,7 +261,7 @@ static int fg_check_for_ima_errors(struct fg_chip *chip)
static int fg_check_iacs_ready(struct fg_chip *chip)
{
- int rc = 0, timeout = 250;
+ int rc = 0, tries = 250;
u8 ima_opr_sts = 0;
/*
@@ -176,17 +281,17 @@ static int fg_check_iacs_ready(struct fg_chip *chip)
if (ima_opr_sts & IACS_RDY_BIT)
break;
- if (!(--timeout))
+ if (!(--tries))
break;
/* delay for iacs_ready to be asserted */
usleep_range(5000, 7000);
}
- if (!timeout) {
+ if (!tries) {
pr_err("IACS_RDY not set\n");
-
- rc = fg_check_for_ima_errors(chip);
+ /* check for error condition */
+ rc = fg_clear_ima_errors_if_any(chip, false);
if (rc < 0) {
pr_err("Failed to check for ima errors rc=%d\n", rc);
return rc;
@@ -250,7 +355,7 @@ static int __fg_interleaved_mem_write(struct fg_chip *chip, u16 address,
}
/* check for error condition */
- rc = fg_check_for_ima_errors(chip);
+ rc = fg_clear_ima_errors_if_any(chip, false);
if (rc < 0) {
pr_err("Failed to check for ima errors rc=%d\n", rc);
return rc;
@@ -296,7 +401,7 @@ static int __fg_interleaved_mem_read(struct fg_chip *chip, u16 address,
offset = 0;
/* check for error condition */
- rc = fg_check_for_ima_errors(chip);
+ rc = fg_clear_ima_errors_if_any(chip, false);
if (rc < 0) {
pr_err("Failed to check for ima errors rc=%d\n", rc);
return rc;
@@ -581,5 +686,19 @@ int fg_ima_init(struct fg_chip *chip)
return rc;
}
+ /* Clear DMA errors if any before clearing IMA errors */
+ rc = fg_clear_dma_errors_if_any(chip);
+ if (rc < 0) {
+ pr_err("Error in checking DMA errors rc:%d\n", rc);
+ return rc;
+ }
+
+ /* Clear IMA errors if any before SRAM transactions can begin */
+ rc = fg_clear_ima_errors_if_any(chip, true);
+ if (rc < 0 && rc != -EAGAIN) {
+ pr_err("Error in checking IMA errors rc:%d\n", rc);
+ return rc;
+ }
+
return 0;
}
diff --git a/drivers/power/qcom-charger/fg-reg.h b/drivers/power/qcom-charger/fg-reg.h
index 431e28a7eb1f..ffc46f328f91 100644
--- a/drivers/power/qcom-charger/fg-reg.h
+++ b/drivers/power/qcom-charger/fg-reg.h
@@ -26,6 +26,9 @@
#define BATT_SOC_LOW_PWR_CFG(chip) (chip->batt_soc_base + 0x52)
#define BATT_SOC_LOW_PWR_STS(chip) (chip->batt_soc_base + 0x56)
+/* BATT_SOC_INT_RT_STS */
+#define MSOC_EMPTY_BIT BIT(5)
+
/* BATT_SOC_EN_CTL */
#define FG_ALGORITHM_EN_BIT BIT(7)
@@ -258,6 +261,7 @@
#define ESR_REQ_CTL_EN_BIT BIT(0)
/* FG_MEM_IF register and bit definitions */
+#define MEM_IF_INT_RT_STS(chip) ((chip->mem_if_base) + 0x10)
#define MEM_IF_MEM_INTF_CFG(chip) ((chip->mem_if_base) + 0x50)
#define MEM_IF_IMA_CTL(chip) ((chip->mem_if_base) + 0x51)
#define MEM_IF_IMA_CFG(chip) ((chip->mem_if_base) + 0x52)
@@ -273,6 +277,11 @@
#define MEM_IF_WR_DATA3(chip) ((chip->mem_if_base) + 0x66)
#define MEM_IF_RD_DATA0(chip) ((chip->mem_if_base) + 0x67)
#define MEM_IF_RD_DATA3(chip) ((chip->mem_if_base) + 0x6A)
+#define MEM_IF_DMA_STS(chip) ((chip->mem_if_base) + 0x70)
+#define MEM_IF_DMA_CTL(chip) ((chip->mem_if_base) + 0x71)
+
+/* MEM_IF_INT_RT_STS */
+#define MEM_XCP_BIT BIT(1)
/* MEM_IF_MEM_INTF_CFG */
#define MEM_ACCESS_REQ_BIT BIT(7)
@@ -286,10 +295,19 @@
/* MEM_IF_IMA_CFG */
#define IACS_CLR_BIT BIT(2)
#define IACS_INTR_SRC_SLCT_BIT BIT(3)
+#define STATIC_CLK_EN_BIT BIT(4)
/* MEM_IF_IMA_OPR_STS */
#define IACS_RDY_BIT BIT(1)
+/* MEM_IF_IMA_EXP_STS */
+#define IACS_ERR_BIT BIT(0)
+#define XCT_TYPE_ERR_BIT BIT(1)
+#define DATA_RD_ERR_BIT BIT(3)
+#define DATA_WR_ERR_BIT BIT(4)
+#define ADDR_BURST_WRAP_BIT BIT(5)
+#define ADDR_STABLE_ERR_BIT BIT(7)
+
/* MEM_IF_IMA_ERR_STS */
#define ADDR_STBL_ERR_BIT BIT(7)
#define WR_ACS_ERR_BIT BIT(6)
@@ -297,4 +315,11 @@
/* MEM_IF_FG_BEAT_COUNT */
#define BEAT_COUNT_MASK GENMASK(3, 0)
+
+/* MEM_IF_DMA_STS */
+#define DMA_WRITE_ERROR_BIT BIT(1)
+#define DMA_READ_ERROR_BIT BIT(2)
+
+/* MEM_IF_DMA_CTL */
+#define DMA_CLEAR_LOG_BIT BIT(0)
#endif
diff --git a/drivers/power/qcom-charger/fg-util.c b/drivers/power/qcom-charger/fg-util.c
index 0e3c7dbb5731..405d875ea7df 100644
--- a/drivers/power/qcom-charger/fg-util.c
+++ b/drivers/power/qcom-charger/fg-util.c
@@ -14,6 +14,82 @@
#include "fg-core.h"
+void fg_circ_buf_add(struct fg_circ_buf *buf, int val)
+{
+ buf->arr[buf->head] = val;
+ buf->head = (buf->head + 1) % ARRAY_SIZE(buf->arr);
+ buf->size = min(++buf->size, (int)ARRAY_SIZE(buf->arr));
+}
+
+void fg_circ_buf_clr(struct fg_circ_buf *buf)
+{
+ memset(buf, 0, sizeof(*buf));
+}
+
+int fg_circ_buf_avg(struct fg_circ_buf *buf, int *avg)
+{
+ s64 result = 0;
+ int i;
+
+ if (buf->size == 0)
+ return -ENODATA;
+
+ for (i = 0; i < buf->size; i++)
+ result += buf->arr[i];
+
+ *avg = div_s64(result, buf->size);
+ return 0;
+}
+
+int fg_lerp(const struct fg_pt *pts, size_t tablesize, s32 input, s32 *output)
+{
+ int i;
+ s64 temp;
+
+ if (pts == NULL) {
+ pr_err("Table is NULL\n");
+ return -EINVAL;
+ }
+
+ if (tablesize < 1) {
+ pr_err("Table has no entries\n");
+ return -ENOENT;
+ }
+
+ if (tablesize == 1) {
+ *output = 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;
+ return 0;
+ }
+
+ if (input >= pts[tablesize - 1].x) {
+ *output = pts[tablesize - 1].y;
+ return 0;
+ }
+
+ for (i = 1; i < tablesize; i++) {
+ if (input >= pts[i].x)
+ continue;
+
+ 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;
+ }
+
+ return -EINVAL;
+}
+
static struct fg_dbgfs dbgfs_data = {
.help_msg = {
.data =
diff --git a/drivers/power/qcom-charger/qpnp-fg-gen3.c b/drivers/power/qcom-charger/qpnp-fg-gen3.c
index 00a3f3ecdc20..100153280d9e 100644
--- a/drivers/power/qcom-charger/qpnp-fg-gen3.c
+++ b/drivers/power/qcom-charger/qpnp-fg-gen3.c
@@ -146,6 +146,8 @@ static void fg_encode_default(struct fg_sram_param *sp,
static struct fg_sram_param pmicobalt_v1_sram_params[] = {
PARAM(BATT_SOC, BATT_SOC_WORD, BATT_SOC_OFFSET, 4, 1, 1, 0, NULL,
fg_decode_default),
+ PARAM(FULL_SOC, FULL_SOC_WORD, FULL_SOC_OFFSET, 2, 1, 1, 0, NULL,
+ fg_decode_default),
PARAM(VOLTAGE_PRED, VOLTAGE_PRED_WORD, VOLTAGE_PRED_OFFSET, 2, 244141,
1000, 0, NULL, fg_decode_voltage_15b),
PARAM(OCV, OCV_WORD, OCV_OFFSET, 2, 244141, 1000, 0, NULL,
@@ -198,6 +200,8 @@ static struct fg_sram_param pmicobalt_v1_sram_params[] = {
static struct fg_sram_param pmicobalt_v2_sram_params[] = {
PARAM(BATT_SOC, BATT_SOC_WORD, BATT_SOC_OFFSET, 4, 1, 1, 0, NULL,
fg_decode_default),
+ PARAM(FULL_SOC, FULL_SOC_WORD, FULL_SOC_OFFSET, 2, 1, 1, 0, NULL,
+ fg_decode_default),
PARAM(VOLTAGE_PRED, VOLTAGE_PRED_WORD, VOLTAGE_PRED_OFFSET, 2, 244141,
1000, 0, NULL, fg_decode_voltage_15b),
PARAM(OCV, OCV_WORD, OCV_OFFSET, 2, 244141, 1000, 0, NULL,
@@ -655,6 +659,35 @@ static int fg_get_msoc_raw(struct fg_chip *chip, int *val)
return 0;
}
+static bool is_batt_empty(struct fg_chip *chip)
+{
+ u8 status;
+ int rc, vbatt_uv, msoc;
+
+ rc = fg_read(chip, BATT_SOC_INT_RT_STS(chip), &status, 1);
+ if (rc < 0) {
+ pr_err("failed to read addr=0x%04x, rc=%d\n",
+ BATT_SOC_INT_RT_STS(chip), rc);
+ return false;
+ }
+
+ if (!(status & MSOC_EMPTY_BIT))
+ return false;
+
+ rc = fg_get_battery_voltage(chip, &vbatt_uv);
+ if (rc < 0) {
+ pr_err("failed to get battery voltage, rc=%d\n", rc);
+ return false;
+ }
+
+ rc = fg_get_msoc_raw(chip, &msoc);
+ if (!rc)
+ pr_warn("batt_soc_rt_sts: %x vbatt: %d uV msoc:%d\n", status,
+ vbatt_uv, msoc);
+
+ return ((vbatt_uv < chip->dt.cutoff_volt_mv * 1000) ? true : false);
+}
+
#define DEBUG_BATT_ID_KOHMS 7
static bool is_debug_batt_id(struct fg_chip *chip)
{
@@ -686,7 +719,7 @@ static int fg_get_prop_capacity(struct fg_chip *chip, int *val)
return 0;
}
- if (chip->charge_empty) {
+ if (is_batt_empty(chip)) {
*val = EMPTY_SOC;
return 0;
}
@@ -1167,11 +1200,11 @@ static void fg_cap_learning_update(struct fg_chip *chip)
batt_soc = (u32)batt_soc >> 24;
fg_dbg(chip, FG_CAP_LEARN, "Chg_status: %d cl_active: %d batt_soc: %d\n",
- chip->status, chip->cl.active, batt_soc);
+ chip->charge_status, chip->cl.active, batt_soc);
/* Initialize the starting point of learning capacity */
if (!chip->cl.active) {
- if (chip->status == POWER_SUPPLY_STATUS_CHARGING) {
+ if (chip->charge_status == POWER_SUPPLY_STATUS_CHARGING) {
rc = fg_cap_learning_begin(chip, batt_soc);
chip->cl.active = (rc == 0);
}
@@ -1187,7 +1220,7 @@ static void fg_cap_learning_update(struct fg_chip *chip)
chip->cl.init_cc_uah = 0;
}
- if (chip->status == POWER_SUPPLY_STATUS_NOT_CHARGING) {
+ if (chip->charge_status == POWER_SUPPLY_STATUS_NOT_CHARGING) {
fg_dbg(chip, FG_CAP_LEARN, "Capacity learning aborted @ battery SOC %d\n",
batt_soc);
chip->cl.active = false;
@@ -1217,7 +1250,7 @@ static int fg_adjust_ki_coeff_dischg(struct fg_chip *chip)
return rc;
}
- if (chip->status == POWER_SUPPLY_STATUS_DISCHARGING) {
+ if (chip->charge_status == POWER_SUPPLY_STATUS_DISCHARGING) {
for (i = KI_COEFF_SOC_LEVELS - 1; i >= 0; i--) {
if (msoc < chip->dt.ki_coeff_soc[i]) {
ki_coeff_med = chip->dt.ki_coeff_med_dischg[i];
@@ -1291,7 +1324,7 @@ static int fg_charge_full_update(struct fg_chip *chip)
}
fg_dbg(chip, FG_STATUS, "msoc: %d health: %d status: %d\n", msoc,
- chip->health, chip->status);
+ chip->health, chip->charge_status);
if (chip->charge_done) {
if (msoc >= 99 && chip->health == POWER_SUPPLY_HEALTH_GOOD)
chip->charge_full = true;
@@ -1409,10 +1442,11 @@ static int fg_esr_fcc_config(struct fg_chip *chip)
parallel_en = prop.intval;
}
- fg_dbg(chip, FG_POWER_SUPPLY, "status: %d parallel_en: %d esr_fcc_ctrl_en: %d\n",
- chip->status, parallel_en, chip->esr_fcc_ctrl_en);
+ fg_dbg(chip, FG_POWER_SUPPLY, "charge_status: %d parallel_en: %d esr_fcc_ctrl_en: %d\n",
+ chip->charge_status, parallel_en, chip->esr_fcc_ctrl_en);
- if (chip->status == POWER_SUPPLY_STATUS_CHARGING && parallel_en) {
+ if (chip->charge_status == POWER_SUPPLY_STATUS_CHARGING &&
+ parallel_en) {
if (chip->esr_fcc_ctrl_en)
return 0;
@@ -1458,6 +1492,21 @@ static int fg_esr_fcc_config(struct fg_chip *chip)
return 0;
}
+static void fg_batt_avg_update(struct fg_chip *chip)
+{
+ if (chip->charge_status == chip->prev_charge_status)
+ return;
+
+ cancel_delayed_work_sync(&chip->batt_avg_work);
+ fg_circ_buf_clr(&chip->ibatt_circ_buf);
+ fg_circ_buf_clr(&chip->vbatt_circ_buf);
+
+ if (chip->charge_status == POWER_SUPPLY_STATUS_CHARGING ||
+ chip->charge_status == POWER_SUPPLY_STATUS_DISCHARGING)
+ schedule_delayed_work(&chip->batt_avg_work,
+ msecs_to_jiffies(2000));
+}
+
static void status_change_work(struct work_struct *work)
{
struct fg_chip *chip = container_of(work,
@@ -1477,7 +1526,16 @@ static void status_change_work(struct work_struct *work)
goto out;
}
- chip->status = prop.intval;
+ chip->prev_charge_status = chip->charge_status;
+ chip->charge_status = prop.intval;
+ rc = power_supply_get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_CHARGE_TYPE, &prop);
+ if (rc < 0) {
+ pr_err("Error in getting charge type, rc=%d\n", rc);
+ goto out;
+ }
+
+ chip->charge_type = prop.intval;
rc = power_supply_get_property(chip->batt_psy,
POWER_SUPPLY_PROP_CHARGE_DONE, &prop);
if (rc < 0) {
@@ -1486,9 +1544,6 @@ static void status_change_work(struct work_struct *work)
}
chip->charge_done = prop.intval;
- fg_dbg(chip, FG_POWER_SUPPLY, "curr_status:%d charge_done: %d\n",
- chip->status, chip->charge_done);
-
if (chip->cyc_ctr.en)
schedule_work(&chip->cycle_count_work);
@@ -1509,7 +1564,12 @@ static void status_change_work(struct work_struct *work)
rc = fg_esr_fcc_config(chip);
if (rc < 0)
pr_err("Error in adjusting FCC for ESR, rc=%d\n", rc);
+
+ fg_batt_avg_update(chip);
+
out:
+ fg_dbg(chip, FG_POWER_SUPPLY, "charge_status:%d charge_type:%d charge_done:%d\n",
+ chip->charge_status, chip->charge_type, chip->charge_done);
pm_relax(chip->dev);
}
@@ -1596,7 +1656,7 @@ static void cycle_count_work(struct work_struct *work)
/* We need only the most significant byte here */
batt_soc = (u32)batt_soc >> 24;
- if (chip->status == POWER_SUPPLY_STATUS_CHARGING) {
+ if (chip->charge_status == POWER_SUPPLY_STATUS_CHARGING) {
/* Find out which bucket the SOC falls in */
bucket = batt_soc / BUCKET_SOC_PCT;
pr_debug("batt_soc: %d bucket: %d\n", batt_soc, bucket);
@@ -1913,6 +1973,229 @@ static struct kernel_param_ops fg_restart_ops = {
module_param_cb(restart, &fg_restart_ops, &fg_restart, 0644);
+#define BATT_AVG_POLL_PERIOD_MS 10000
+static void batt_avg_work(struct work_struct *work)
+{
+ struct fg_chip *chip = container_of(work, struct fg_chip,
+ batt_avg_work.work);
+ int rc, ibatt_now, vbatt_now;
+
+ mutex_lock(&chip->batt_avg_lock);
+ rc = fg_get_battery_current(chip, &ibatt_now);
+ if (rc < 0) {
+ pr_err("failed to get battery current, rc=%d\n", rc);
+ goto reschedule;
+ }
+
+ rc = fg_get_battery_voltage(chip, &vbatt_now);
+ if (rc < 0) {
+ pr_err("failed to get battery voltage, rc=%d\n", rc);
+ goto reschedule;
+ }
+
+ fg_circ_buf_add(&chip->ibatt_circ_buf, ibatt_now);
+ fg_circ_buf_add(&chip->vbatt_circ_buf, vbatt_now);
+
+reschedule:
+ mutex_unlock(&chip->batt_avg_lock);
+ schedule_delayed_work(&chip->batt_avg_work,
+ 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
+#define MICRO_UNIT 1000000
+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;
+ s64 t_predicted_cc = 0, t_predicted_cv = 0;
+
+ if (chip->bp.float_volt_uv <= 0) {
+ pr_err("battery profile is not loaded\n");
+ return -ENODATA;
+ }
+
+ if (!is_charger_available(chip)) {
+ fg_dbg(chip, FG_TTF, "charger is not available\n");
+ return -ENODATA;
+ }
+
+ if (chip->charge_status == POWER_SUPPLY_STATUS_FULL) {
+ *val = 0;
+ return 0;
+ }
+
+ mutex_lock(&chip->batt_avg_lock);
+ rc = fg_circ_buf_avg(&chip->ibatt_circ_buf, &ibatt_avg);
+ if (rc < 0) {
+ /* try to get instantaneous current */
+ rc = fg_get_battery_current(chip, &ibatt_avg);
+ if (rc < 0) {
+ mutex_unlock(&chip->batt_avg_lock);
+ pr_err("failed to get battery current, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ rc = fg_circ_buf_avg(&chip->vbatt_circ_buf, &vbatt_avg);
+ if (rc < 0) {
+ /* try to get instantaneous voltage */
+ rc = fg_get_battery_voltage(chip, &vbatt_avg);
+ if (rc < 0) {
+ mutex_unlock(&chip->batt_avg_lock);
+ pr_err("failed to get battery voltage, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ mutex_unlock(&chip->batt_avg_lock);
+ fg_dbg(chip, FG_TTF, "vbatt_avg=%d\n", vbatt_avg);
+
+ /* clamp ibatt_avg to -150mA */
+ if (ibatt_avg > -150000)
+ ibatt_avg = -150000;
+ fg_dbg(chip, FG_TTF, "ibatt_avg=%d\n", ibatt_avg);
+
+ /* reverse polarity to be consistent with unsigned current settings */
+ ibatt_avg = abs(ibatt_avg);
+
+ /* estimated battery current at the CC to CV transition */
+ i_cc2cv = div_s64((s64)ibatt_avg * vbatt_avg, chip->bp.float_volt_uv);
+ fg_dbg(chip, FG_TTF, "i_cc2cv=%d\n", i_cc2cv);
+
+ rc = fg_get_battery_resistance(chip, &rbatt);
+ if (rc < 0) {
+ pr_err("failed to get battery resistance rc=%d\n", rc);
+ return rc;
+ }
+
+ /* clamp rbatt to 50mOhms */
+ if (rbatt < 50000)
+ rbatt = 50000;
+
+ fg_dbg(chip, FG_TTF, "rbatt=%d\n", rbatt);
+
+ rc = fg_get_sram_prop(chip, FG_SRAM_ACT_BATT_CAP, &act_cap_uah);
+ if (rc < 0) {
+ pr_err("failed to get ACT_BATT_CAP rc=%d\n", rc);
+ return rc;
+ }
+ act_cap_uah *= MILLI_UNIT;
+ fg_dbg(chip, FG_TTF, "actual_capacity_uah=%d\n", act_cap_uah);
+
+ rc = fg_get_prop_capacity(chip, &msoc);
+ if (rc < 0) {
+ pr_err("failed to get msoc rc=%d\n", rc);
+ return rc;
+ }
+ fg_dbg(chip, FG_TTF, "msoc=%d\n", msoc);
+
+ rc = fg_get_sram_prop(chip, FG_SRAM_FULL_SOC, &full_soc);
+ if (rc < 0) {
+ pr_err("failed to get full soc rc=%d\n", rc);
+ return rc;
+ }
+ full_soc = DIV_ROUND_CLOSEST(((u16)full_soc >> 8) * FULL_CAPACITY,
+ FULL_SOC_RAW);
+ fg_dbg(chip, FG_TTF, "full_soc=%d\n", full_soc);
+
+ /* if we are already in CV state then we can skip estimating CC */
+ if (chip->charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER)
+ goto skip_cc_estimate;
+
+ /* if the charger is current limited then use power approximation */
+ if (ibatt_avg > chip->bp.fastchg_curr_ma * MILLI_UNIT - 50000)
+ ocv_cc2cv = div_s64((s64)rbatt * ibatt_avg, MICRO_UNIT);
+ else
+ ocv_cc2cv = div_s64((s64)rbatt * i_cc2cv, MICRO_UNIT);
+ ocv_cc2cv = chip->bp.float_volt_uv - ocv_cc2cv;
+ fg_dbg(chip, FG_TTF, "ocv_cc2cv=%d\n", ocv_cc2cv);
+
+ soc_cc2cv = div_s64(chip->bp.float_volt_uv - ocv_cc2cv, OCV_SLOPE_UV);
+ /* estimated SOC at the CC to CV transition */
+ soc_cc2cv = 100 - soc_cc2cv;
+ fg_dbg(chip, FG_TTF, "soc_cc2cv=%d\n", soc_cc2cv);
+
+ /* the esimated SOC may be lower than the current SOC */
+ if (soc_cc2cv - msoc <= 0)
+ goto skip_cc_estimate;
+
+ t_predicted_cc = div_s64((s64)full_soc * act_cap_uah, 100);
+ t_predicted_cc = div_s64(t_predicted_cc * (soc_cc2cv - msoc), 100);
+ t_predicted_cc *= HOURS_TO_SECONDS;
+ t_predicted_cc = div_s64(t_predicted_cc, (ibatt_avg + i_cc2cv) / 2);
+
+skip_cc_estimate:
+ fg_dbg(chip, FG_TTF, "t_predicted_cc=%lld\n", t_predicted_cc);
+
+ /* CV estimate starts here */
+ if (chip->charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER)
+ ln_val = ibatt_avg / abs(chip->dt.sys_term_curr_ma);
+ else
+ ln_val = i_cc2cv / abs(chip->dt.sys_term_curr_ma);
+
+ 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 * 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);
+ *val = t_predicted_cc + t_predicted_cv;
+ return 0;
+}
+
+#define CENTI_ICORRECT_C0 105
+#define CENTI_ICORRECT_C1 20
+static int fg_get_time_to_empty(struct fg_chip *chip, int *val)
+{
+ int rc, ibatt_avg, msoc, act_cap_uah;
+ s32 divisor;
+ s64 t_predicted;
+
+ rc = fg_circ_buf_avg(&chip->ibatt_circ_buf, &ibatt_avg);
+ if (rc < 0) {
+ /* try to get instantaneous current */
+ rc = fg_get_battery_current(chip, &ibatt_avg);
+ if (rc < 0) {
+ pr_err("failed to get battery current, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ /* clamp ibatt_avg to 150mA */
+ if (ibatt_avg < 150000)
+ ibatt_avg = 150000;
+
+ rc = fg_get_sram_prop(chip, FG_SRAM_ACT_BATT_CAP, &act_cap_uah);
+ if (rc < 0) {
+ pr_err("Error in getting ACT_BATT_CAP, rc=%d\n", rc);
+ return rc;
+ }
+ act_cap_uah *= MILLI_UNIT;
+
+ rc = fg_get_prop_capacity(chip, &msoc);
+ if (rc < 0) {
+ pr_err("Error in getting capacity, rc=%d\n", rc);
+ return rc;
+ }
+
+ t_predicted = div_s64((s64)msoc * act_cap_uah, 100);
+ t_predicted *= HOURS_TO_SECONDS;
+ divisor = CENTI_ICORRECT_C0 * 100 + CENTI_ICORRECT_C1 * msoc;
+ divisor = div_s64((s64)divisor * ibatt_avg, 10000);
+ if (divisor > 0)
+ t_predicted = div_s64(t_predicted, divisor);
+
+ *val = t_predicted;
+ return 0;
+}
+
/* PSY CALLBACKS STAY HERE */
static int fg_psy_get_property(struct power_supply *psy,
@@ -1974,11 +2257,22 @@ static int fg_psy_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_CHARGE_COUNTER:
rc = fg_get_cc_soc_sw(chip, &pval->intval);
break;
+ case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
+ rc = fg_get_time_to_full(chip, &pval->intval);
+ break;
+ case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
+ rc = fg_get_time_to_empty(chip, &pval->intval);
+ break;
default:
+ pr_err("unsupported property %d\n", psp);
+ rc = -EINVAL;
break;
}
- return rc;
+ if (rc < 0)
+ return -ENODATA;
+
+ return 0;
}
static int fg_psy_set_property(struct power_supply *psy,
@@ -2061,6 +2355,8 @@ static enum power_supply_property fg_psy_props[] = {
POWER_SUPPLY_PROP_CHARGE_NOW,
POWER_SUPPLY_PROP_CHARGE_FULL,
POWER_SUPPLY_PROP_CHARGE_COUNTER,
+ POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
};
static const struct power_supply_desc fg_psy_desc = {
@@ -2267,6 +2563,37 @@ static int fg_memif_init(struct fg_chip *chip)
/* INTERRUPT HANDLERS STAY HERE */
+static irqreturn_t fg_mem_xcp_irq_handler(int irq, void *data)
+{
+ struct fg_chip *chip = data;
+ u8 status;
+ int rc;
+
+ rc = fg_read(chip, MEM_IF_INT_RT_STS(chip), &status, 1);
+ if (rc < 0) {
+ pr_err("failed to read addr=0x%04x, rc=%d\n",
+ MEM_IF_INT_RT_STS(chip), rc);
+ return IRQ_HANDLED;
+ }
+
+ fg_dbg(chip, FG_IRQ, "irq %d triggered, status:%d\n", irq, status);
+ if (status & MEM_XCP_BIT) {
+ rc = fg_clear_dma_errors_if_any(chip);
+ if (rc < 0) {
+ pr_err("Error in clearing DMA error, rc=%d\n", rc);
+ return IRQ_HANDLED;
+ }
+
+ mutex_lock(&chip->sram_rw_lock);
+ rc = fg_clear_ima_errors_if_any(chip, true);
+ if (rc < 0 && rc != -EAGAIN)
+ pr_err("Error in checking IMA errors rc:%d\n", rc);
+ mutex_unlock(&chip->sram_rw_lock);
+ }
+
+ return IRQ_HANDLED;
+}
+
static irqreturn_t fg_vbatt_low_irq_handler(int irq, void *data)
{
struct fg_chip *chip = data;
@@ -2363,14 +2690,10 @@ static irqreturn_t fg_delta_soc_irq_handler(int irq, void *data)
struct fg_chip *chip = data;
int rc;
+ fg_dbg(chip, FG_IRQ, "irq %d triggered\n", irq);
if (chip->cyc_ctr.en)
schedule_work(&chip->cycle_count_work);
- if (is_charger_available(chip))
- power_supply_changed(chip->batt_psy);
-
- fg_dbg(chip, FG_IRQ, "irq %d triggered\n", irq);
-
if (chip->cl.active)
fg_cap_learning_update(chip);
@@ -2382,6 +2705,9 @@ 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);
+ if (is_charger_available(chip))
+ power_supply_changed(chip->batt_psy);
+
return IRQ_HANDLED;
}
@@ -2389,11 +2715,10 @@ static irqreturn_t fg_empty_soc_irq_handler(int irq, void *data)
{
struct fg_chip *chip = data;
- chip->charge_empty = true;
+ fg_dbg(chip, FG_IRQ, "irq %d triggered\n", irq);
if (is_charger_available(chip))
power_supply_changed(chip->batt_psy);
- fg_dbg(chip, FG_IRQ, "irq %d triggered\n", irq);
return IRQ_HANDLED;
}
@@ -2407,9 +2732,7 @@ static irqreturn_t fg_soc_irq_handler(int irq, void *data)
static irqreturn_t fg_dummy_irq_handler(int irq, void *data)
{
- struct fg_chip *chip = data;
-
- fg_dbg(chip, FG_IRQ, "irq %d triggered\n", irq);
+ pr_debug("irq %d triggered\n", irq);
return IRQ_HANDLED;
}
@@ -2483,7 +2806,7 @@ static struct fg_irq_info fg_irqs[FG_IRQ_MAX] = {
},
[MEM_XCP_IRQ] = {
.name = "mem-xcp",
- .handler = fg_dummy_irq_handler,
+ .handler = fg_mem_xcp_irq_handler,
},
[IMA_RDY_IRQ] = {
.name = "ima-rdy",
@@ -2899,7 +3222,7 @@ static int fg_gen3_probe(struct platform_device *pdev)
{
struct fg_chip *chip;
struct power_supply_config fg_psy_cfg;
- int rc;
+ int rc, msoc, volt_uv, batt_temp;
chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
@@ -2908,6 +3231,8 @@ static int fg_gen3_probe(struct platform_device *pdev)
chip->dev = &pdev->dev;
chip->debug_mask = &fg_gen3_debug_mask;
chip->irqs = fg_irqs;
+ chip->charge_status = -EINVAL;
+ chip->prev_charge_status = -EINVAL;
chip->regmap = dev_get_regmap(chip->dev->parent, NULL);
if (!chip->regmap) {
dev_err(chip->dev, "Parent regmap is unavailable\n");
@@ -2932,11 +3257,13 @@ static int fg_gen3_probe(struct platform_device *pdev)
mutex_init(&chip->sram_rw_lock);
mutex_init(&chip->cyc_ctr.lock);
mutex_init(&chip->cl.lock);
+ mutex_init(&chip->batt_avg_lock);
init_completion(&chip->soc_update);
init_completion(&chip->soc_ready);
INIT_DELAYED_WORK(&chip->profile_load_work, profile_load_work);
INIT_WORK(&chip->status_change_work, status_change_work);
INIT_WORK(&chip->cycle_count_work, cycle_count_work);
+ INIT_DELAYED_WORK(&chip->batt_avg_work, batt_avg_work);
rc = fg_memif_init(chip);
if (rc < 0) {
@@ -2992,11 +3319,22 @@ static int fg_gen3_probe(struct platform_device *pdev)
goto exit;
}
+ rc = fg_get_battery_voltage(chip, &volt_uv);
+ if (!rc)
+ rc = fg_get_prop_capacity(chip, &msoc);
+
+ if (!rc)
+ rc = fg_get_battery_temp(chip, &batt_temp);
+
+ if (!rc)
+ pr_info("battery SOC:%d voltage: %duV temp: %d id: %dKOhms\n",
+ msoc, volt_uv, batt_temp, chip->batt_id_kohms);
+
+ device_init_wakeup(chip->dev, true);
if (chip->profile_available)
schedule_delayed_work(&chip->profile_load_work, 0);
- device_init_wakeup(chip->dev, true);
- pr_debug("FG GEN3 driver successfully probed\n");
+ pr_debug("FG GEN3 driver probed successfully\n");
return 0;
exit:
fg_cleanup(chip);
@@ -3018,6 +3356,7 @@ static int fg_gen3_suspend(struct device *dev)
}
}
+ cancel_delayed_work_sync(&chip->batt_avg_work);
return 0;
}
@@ -3036,6 +3375,9 @@ static int fg_gen3_resume(struct device *dev)
}
}
+ fg_circ_buf_clr(&chip->ibatt_circ_buf);
+ fg_circ_buf_clr(&chip->vbatt_circ_buf);
+ schedule_delayed_work(&chip->batt_avg_work, 0);
return 0;
}
diff --git a/drivers/power/qcom-charger/qpnp-smb2.c b/drivers/power/qcom-charger/qpnp-smb2.c
index a00ad8343a88..6968ab2ab11c 100644
--- a/drivers/power/qcom-charger/qpnp-smb2.c
+++ b/drivers/power/qcom-charger/qpnp-smb2.c
@@ -1049,6 +1049,7 @@ static int smb2_init_hw(struct smb2 *chip)
{
struct smb_charger *chg = &chip->chg;
int rc;
+ u8 stat;
if (chip->dt.no_battery)
chg->fake_capacity = 50;
@@ -1069,6 +1070,21 @@ static int smb2_init_hw(struct smb2 *chip)
chg->otg_cl_ua = chip->dt.otg_cl_ua;
+ rc = smblib_read(chg, APSD_RESULT_STATUS_REG, &stat);
+ if (rc < 0) {
+ pr_err("Couldn't read APSD_RESULT_STATUS rc=%d\n", rc);
+ return rc;
+ }
+
+ /* clear the ICL override if it is set */
+ if (stat & ICL_OVERRIDE_LATCH_BIT) {
+ rc = smblib_write(chg, CMD_APSD_REG, ICL_OVERRIDE_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't disable ICL override rc=%d\n", rc);
+ return rc;
+ }
+ }
+
/* votes must be cast before configuring software control */
vote(chg->pl_disable_votable,
PL_INDIRECT_VOTER, true, 0);
@@ -1161,6 +1177,15 @@ static int smb2_init_hw(struct smb2 *chip)
return rc;
}
+ /* increase VCONN softstart */
+ rc = smblib_masked_write(chg, TYPE_C_CFG_2_REG,
+ VCONN_SOFTSTART_CFG_MASK, VCONN_SOFTSTART_CFG_MASK);
+ if (rc < 0) {
+ dev_err(chg->dev, "Couldn't increase VCONN softstart rc=%d\n",
+ rc);
+ return rc;
+ }
+
rc = smblib_masked_write(chg, QNOVO_PT_ENABLE_CMD_REG,
QNOVO_PT_ENABLE_CMD_BIT, QNOVO_PT_ENABLE_CMD_BIT);
if (rc < 0) {
@@ -1183,13 +1208,12 @@ static int smb2_init_hw(struct smb2 *chip)
return rc;
}
- /* configure PMI stat output to enable and disable parallel charging */
+ /* disable SW STAT override */
rc = smblib_masked_write(chg, STAT_CFG_REG,
- STAT_PARALLEL_CFG_BIT | STAT_SW_OVERRIDE_CFG_BIT,
- STAT_PARALLEL_CFG_BIT);
+ STAT_SW_OVERRIDE_CFG_BIT, 0);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure signal for parallel rc=%d\n", rc);
+ dev_err(chg->dev, "Couldn't disable SW STAT override rc=%d\n",
+ rc);
return rc;
}
@@ -1287,6 +1311,8 @@ static int smb2_setup_wa_flags(struct smb2 *chip)
chip->chg.wa_flags |= BOOST_BACK_WA;
if (pmic_rev_id->rev4 == PMICOBALT_V1P1_REV4) /* PMI rev 1.1 */
chg->wa_flags |= QC_CHARGER_DETECTION_WA_BIT;
+ if (pmic_rev_id->rev4 == PMICOBALT_V2P0_REV4) /* PMI rev 2.0 */
+ chg->wa_flags |= TYPEC_CC2_REMOVAL_WA_BIT;
break;
default:
pr_err("PMIC subtype %d not supported\n",
diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c
index 9cbba5a34195..6aae7d49271f 100644
--- a/drivers/power/qcom-charger/smb-lib.c
+++ b/drivers/power/qcom-charger/smb-lib.c
@@ -961,12 +961,13 @@ static int smblib_apsd_disable_vote_callback(struct votable *votable,
* OTG REGULATOR *
*****************/
-#define OTG_SOFT_START_DELAY_MS 20
+#define MAX_SOFTSTART_TRIES 2
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;
rc = smblib_masked_write(chg, OTG_ENG_OTG_CFG_REG,
ENG_BUCKBOOST_HALT1_8_MODE_BIT,
@@ -983,14 +984,25 @@ int smblib_vbus_regulator_enable(struct regulator_dev *rdev)
return rc;
}
- msleep(OTG_SOFT_START_DELAY_MS);
- 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);
+ /* 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 rc;
}
@@ -1452,21 +1464,17 @@ int smblib_set_prop_system_temp_level(struct smb_charger *chg,
int smblib_get_prop_dc_present(struct smb_charger *chg,
union power_supply_propval *val)
{
- int rc = 0;
+ int rc;
u8 stat;
- rc = smblib_read(chg, DC_INT_RT_STS_REG, &stat);
+ rc = smblib_read(chg, DCIN_BASE + INT_RT_STS_OFFSET, &stat);
if (rc < 0) {
- smblib_err(chg, "Couldn't read DC_INT_RT_STS_REG rc=%d\n",
- rc);
+ smblib_err(chg, "Couldn't read DCIN_RT_STS rc=%d\n", rc);
return rc;
}
- smblib_dbg(chg, PR_REGISTER, "DC_INT_RT_STS_REG = 0x%02x\n",
- stat);
val->intval = (bool)(stat & DCIN_PLUGIN_RT_STS_BIT);
-
- return rc;
+ return 0;
}
int smblib_get_prop_dc_online(struct smb_charger *chg,
@@ -1522,20 +1530,17 @@ int smblib_set_prop_dc_current_max(struct smb_charger *chg,
int smblib_get_prop_usb_present(struct smb_charger *chg,
union power_supply_propval *val)
{
- int rc = 0;
+ int rc;
u8 stat;
- rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat);
+ rc = smblib_read(chg, USBIN_BASE + INT_RT_STS_OFFSET, &stat);
if (rc < 0) {
- smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc);
+ smblib_err(chg, "Couldn't read USBIN_RT_STS rc=%d\n", rc);
return rc;
}
- smblib_dbg(chg, PR_REGISTER, "TYPE_C_STATUS_4 = 0x%02x\n",
- stat);
-
- val->intval = (bool)(stat & CC_ATTACHED_BIT);
- return rc;
+ val->intval = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT);
+ return 0;
}
int smblib_get_prop_usb_online(struct smb_charger *chg,
@@ -2002,6 +2007,45 @@ int smblib_set_prop_pd_active(struct smb_charger *chg,
"Couldn't enable vconn on CC line rc=%d\n", rc);
return rc;
}
+
+ rc = vote(chg->usb_icl_votable, PD_VOTER, true, USBIN_500MA);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't vote for USB ICL rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG,
+ USBIN_MODE_CHG_BIT, USBIN_MODE_CHG_BIT);
+ if (rc < 0) {
+ smblib_err(chg,
+ "Couldn't change USB mode rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = smblib_masked_write(chg, CMD_APSD_REG,
+ ICL_OVERRIDE_BIT, ICL_OVERRIDE_BIT);
+ if (rc < 0) {
+ smblib_err(chg,
+ "Couldn't override APSD rc=%d\n", rc);
+ return rc;
+ }
+ } else {
+ rc = smblib_masked_write(chg, CMD_APSD_REG,
+ ICL_OVERRIDE_BIT, 0);
+ if (rc < 0) {
+ smblib_err(chg,
+ "Couldn't override APSD rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG,
+ USBIN_MODE_CHG_BIT, 0);
+ if (rc < 0) {
+ smblib_err(chg,
+ "Couldn't change USB mode rc=%d\n", rc);
+ return rc;
+ }
}
/* CC pin selection s/w override in PD session; h/w otherwise. */
@@ -2078,6 +2122,100 @@ int smblib_reg_block_restore(struct smb_charger *chg,
return rc;
}
+static struct reg_info cc2_detach_settings[] = {
+ {
+ .reg = TYPE_C_CFG_2_REG,
+ .mask = TYPE_C_UFP_MODE_BIT | EN_TRY_SOURCE_MODE_BIT,
+ .val = TYPE_C_UFP_MODE_BIT,
+ .desc = "TYPE_C_CFG_2_REG",
+ },
+ {
+ .reg = TYPE_C_CFG_3_REG,
+ .mask = EN_TRYSINK_MODE_BIT,
+ .val = 0,
+ .desc = "TYPE_C_CFG_3_REG",
+ },
+ {
+ .reg = TAPER_TIMER_SEL_CFG_REG,
+ .mask = TYPEC_SPARE_CFG_BIT,
+ .val = TYPEC_SPARE_CFG_BIT,
+ .desc = "TAPER_TIMER_SEL_CFG_REG",
+ },
+ {
+ .reg = TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
+ .mask = VCONN_EN_ORIENTATION_BIT,
+ .val = 0,
+ .desc = "TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG",
+ },
+ {
+ .reg = MISC_CFG_REG,
+ .mask = TCC_DEBOUNCE_20MS_BIT,
+ .val = TCC_DEBOUNCE_20MS_BIT,
+ .desc = "Tccdebounce time"
+ },
+ {
+ },
+};
+
+static int smblib_cc2_sink_removal_enter(struct smb_charger *chg)
+{
+ int rc = 0;
+ union power_supply_propval cc2_val = {0, };
+
+ if ((chg->wa_flags & TYPEC_CC2_REMOVAL_WA_BIT) == 0)
+ return rc;
+
+ if (chg->cc2_sink_detach_flag != CC2_SINK_NONE)
+ return rc;
+
+ rc = smblib_get_prop_typec_cc_orientation(chg, &cc2_val);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't get cc orientation rc=%d\n", rc);
+ return rc;
+ }
+ if (cc2_val.intval == 1)
+ return rc;
+
+ rc = smblib_get_prop_typec_mode(chg, &cc2_val);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't get prop typec mode rc=%d\n", rc);
+ return rc;
+ }
+
+ switch (cc2_val.intval) {
+ case POWER_SUPPLY_TYPEC_SOURCE_DEFAULT:
+ smblib_reg_block_update(chg, cc2_detach_settings);
+ chg->cc2_sink_detach_flag = CC2_SINK_STD;
+ schedule_work(&chg->rdstd_cc2_detach_work);
+ break;
+ case POWER_SUPPLY_TYPEC_SOURCE_MEDIUM:
+ case POWER_SUPPLY_TYPEC_SOURCE_HIGH:
+ chg->cc2_sink_detach_flag = CC2_SINK_MEDIUM_HIGH;
+ break;
+ default:
+ break;
+ }
+
+ return rc;
+}
+
+static int smblib_cc2_sink_removal_exit(struct smb_charger *chg)
+{
+ int rc = 0;
+
+ if ((chg->wa_flags & TYPEC_CC2_REMOVAL_WA_BIT) == 0)
+ return rc;
+
+ if (chg->cc2_sink_detach_flag == CC2_SINK_STD) {
+ cancel_work_sync(&chg->rdstd_cc2_detach_work);
+ smblib_reg_block_restore(chg, cc2_detach_settings);
+ }
+
+ chg->cc2_sink_detach_flag = CC2_SINK_NONE;
+
+ return rc;
+}
+
int smblib_set_prop_pd_in_hard_reset(struct smb_charger *chg,
const union power_supply_propval *val)
{
@@ -2086,9 +2224,24 @@ int smblib_set_prop_pd_in_hard_reset(struct smb_charger *chg,
rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
EXIT_SNK_BASED_ON_CC_BIT,
(val->intval) ? EXIT_SNK_BASED_ON_CC_BIT : 0);
+ if (rc < 0) {
+ smblib_err(chg, "Could not set EXIT_SNK_BASED_ON_CC rc=%d\n",
+ rc);
+ return rc;
+ }
vote(chg->apsd_disable_votable, PD_HARD_RESET_VOTER, val->intval, 0);
+ if (val->intval)
+ rc = smblib_cc2_sink_removal_enter(chg);
+ else
+ rc = smblib_cc2_sink_removal_exit(chg);
+
+ if (rc < 0) {
+ smblib_err(chg, "Could not detect cc2 removal rc=%d\n", rc);
+ return rc;
+ }
+
return rc;
}
@@ -2259,6 +2412,7 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
struct smb_charger *chg = irq_data->parent_data;
int rc;
u8 stat;
+ bool vbus_rising;
rc = smblib_read(chg, USBIN_BASE + INT_RT_STS_OFFSET, &stat);
if (rc < 0) {
@@ -2266,9 +2420,9 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
return IRQ_HANDLED;
}
- chg->vbus_present = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT);
+ vbus_rising = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT);
smblib_set_opt_freq_buck(chg,
- chg->vbus_present ? FSW_600HZ_FOR_5V : FSW_1MHZ_FOR_REMOVAL);
+ vbus_rising ? FSW_600HZ_FOR_5V : FSW_1MHZ_FOR_REMOVAL);
/* fetch the DPDM regulator */
if (!chg->dpdm_reg && of_get_property(chg->dev->of_node,
@@ -2281,7 +2435,7 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
}
}
- if (chg->vbus_present) {
+ if (vbus_rising) {
if (chg->dpdm_reg && !regulator_is_enabled(chg->dpdm_reg)) {
smblib_dbg(chg, PR_MISC, "enabling DPDM regulator\n");
rc = regulator_enable(chg->dpdm_reg);
@@ -2308,7 +2462,7 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
power_supply_changed(chg->usb_psy);
smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s %s\n",
- irq_data->name, chg->vbus_present ? "attached" : "detached");
+ irq_data->name, vbus_rising ? "attached" : "detached");
return IRQ_HANDLED;
}
@@ -2675,6 +2829,24 @@ static void smblib_handle_typec_debounce_done(struct smb_charger *chg,
if (rc < 0)
smblib_err(chg, "Couldn't get prop typec mode rc=%d\n", rc);
+ /*
+ * HW BUG - after cable is removed, medium or high rd reading
+ * falls to std. Use it for signal of typec cc detachment in
+ * software WA.
+ */
+ if (chg->cc2_sink_detach_flag == CC2_SINK_MEDIUM_HIGH
+ && pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) {
+
+ chg->cc2_sink_detach_flag = CC2_SINK_WA_DONE;
+
+ rc = smblib_masked_write(chg,
+ TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
+ EXIT_SNK_BASED_ON_CC_BIT, 0);
+ if (rc < 0)
+ smblib_err(chg, "Couldn't get prop typec mode rc=%d\n",
+ rc);
+ }
+
smblib_dbg(chg, PR_INTERRUPT, "IRQ: debounce-done %s; Type-C %s detected\n",
rising ? "rising" : "falling",
smblib_typec_mode_name[pval.intval]);
@@ -2688,6 +2860,10 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data)
u8 stat;
bool debounce_done, sink_attached, legacy_cable;
+ /* WA - not when PD hard_reset WIP on cc2 in sink mode */
+ if (chg->cc2_sink_detach_flag == CC2_SINK_STD)
+ return IRQ_HANDLED;
+
rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat);
if (rc < 0) {
smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc);
@@ -2830,7 +3006,9 @@ static void smblib_pl_taper_work(struct work_struct *work)
union power_supply_propval pval = {0, };
int rc;
+ smblib_dbg(chg, PR_PARALLEL, "starting parallel taper work\n");
if (chg->pl.slave_fcc_ua < MINIMUM_PARALLEL_FCC_UA) {
+ smblib_dbg(chg, PR_PARALLEL, "parallel taper is done\n");
vote(chg->pl_disable_votable, TAPER_END_VOTER, true, 0);
goto done;
}
@@ -2842,6 +3020,7 @@ static void smblib_pl_taper_work(struct work_struct *work)
}
if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER) {
+ smblib_dbg(chg, PR_PARALLEL, "master is taper charging; reducing slave FCC\n");
vote(chg->awake_votable, PL_TAPER_WORK_RUNNING_VOTER, true, 0);
/* Reduce the taper percent by 25 percent */
chg->pl.taper_pct = chg->pl.taper_pct
@@ -2855,6 +3034,8 @@ static void smblib_pl_taper_work(struct work_struct *work)
/*
* Master back to Fast Charge, get out of this round of taper reduction
*/
+ smblib_dbg(chg, PR_PARALLEL, "master is fast charging; waiting for next taper\n");
+
done:
vote(chg->awake_votable, PL_TAPER_WORK_RUNNING_VOTER, false, 0);
}
@@ -2867,6 +3048,74 @@ static void clear_hdc_work(struct work_struct *work)
chg->is_hdc = 0;
}
+static void rdstd_cc2_detach_work(struct work_struct *work)
+{
+ int rc;
+ u8 stat;
+ struct smb_irq_data irq_data = {NULL, "cc2-removal-workaround"};
+ struct smb_charger *chg = container_of(work, struct smb_charger,
+ rdstd_cc2_detach_work);
+
+ /*
+ * WA steps -
+ * 1. Enable both UFP and DFP, wait for 10ms.
+ * 2. Disable DFP, wait for 30ms.
+ * 3. Removal detected if both TYPEC_DEBOUNCE_DONE_STATUS
+ * and TIMER_STAGE bits are gone, otherwise repeat all by
+ * work rescheduling.
+ * Note, work will be cancelled when pd_hard_reset is 0.
+ */
+
+ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
+ UFP_EN_CMD_BIT | DFP_EN_CMD_BIT,
+ UFP_EN_CMD_BIT | DFP_EN_CMD_BIT);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't write TYPE_C_CTRL_REG rc=%d\n", rc);
+ return;
+ }
+
+ usleep_range(10000, 11000);
+
+ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
+ UFP_EN_CMD_BIT | DFP_EN_CMD_BIT,
+ UFP_EN_CMD_BIT);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't write TYPE_C_CTRL_REG rc=%d\n", rc);
+ return;
+ }
+
+ usleep_range(30000, 31000);
+
+ rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n",
+ rc);
+ return;
+ }
+ if (stat & TYPEC_DEBOUNCE_DONE_STATUS_BIT)
+ goto rerun;
+
+ rc = smblib_read(chg, TYPE_C_STATUS_5_REG, &stat);
+ if (rc < 0) {
+ smblib_err(chg,
+ "Couldn't read TYPE_C_STATUS_5_REG rc=%d\n", rc);
+ return;
+ }
+ if (stat & TIMER_STAGE_2_BIT)
+ goto rerun;
+
+ /* Bingo, cc2 removal detected */
+ smblib_reg_block_restore(chg, cc2_detach_settings);
+ chg->cc2_sink_detach_flag = CC2_SINK_WA_DONE;
+ irq_data.parent_data = chg;
+ smblib_handle_usb_typec_change(0, &irq_data);
+
+ return;
+
+rerun:
+ schedule_work(&chg->rdstd_cc2_detach_work);
+}
+
static int smblib_create_votables(struct smb_charger *chg)
{
int rc = 0;
@@ -3049,6 +3298,7 @@ int smblib_init(struct smb_charger *chg)
mutex_init(&chg->write_lock);
INIT_WORK(&chg->bms_update_work, bms_update_work);
INIT_WORK(&chg->pl_detect_work, smblib_pl_detect_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->pl_taper_work, smblib_pl_taper_work);
INIT_DELAYED_WORK(&chg->step_soc_req_work, step_soc_req_work);
diff --git a/drivers/power/qcom-charger/smb-lib.h b/drivers/power/qcom-charger/smb-lib.h
index 2809ddadbd90..a0237412ee8b 100644
--- a/drivers/power/qcom-charger/smb-lib.h
+++ b/drivers/power/qcom-charger/smb-lib.h
@@ -54,9 +54,17 @@ enum smb_mode {
NUM_MODES,
};
+enum cc2_sink_type {
+ CC2_SINK_NONE = 0,
+ CC2_SINK_STD,
+ CC2_SINK_MEDIUM_HIGH,
+ CC2_SINK_WA_DONE,
+};
+
enum {
- QC_CHARGER_DETECTION_WA_BIT = BIT(0),
- BOOST_BACK_WA = BIT(1),
+ QC_CHARGER_DETECTION_WA_BIT = BIT(0),
+ BOOST_BACK_WA = BIT(1),
+ TYPEC_CC2_REMOVAL_WA_BIT = BIT(2),
};
struct smb_regulator {
@@ -177,6 +185,7 @@ struct smb_charger {
/* work */
struct work_struct bms_update_work;
struct work_struct pl_detect_work;
+ struct work_struct rdstd_cc2_detach_work;
struct delayed_work hvdcp_detect_work;
struct delayed_work ps_change_timeout_work;
struct delayed_work pl_taper_work;
@@ -187,7 +196,6 @@ struct smb_charger {
int voltage_min_uv;
int voltage_max_uv;
int pd_active;
- bool vbus_present;
bool system_suspend_supported;
int system_temp_level;
@@ -205,6 +213,7 @@ struct smb_charger {
/* workaround flag */
u32 wa_flags;
+ enum cc2_sink_type cc2_sink_detach_flag;
};
int smblib_read(struct smb_charger *chg, u16 addr, u8 *val);
diff --git a/drivers/power/qcom-charger/smb-reg.h b/drivers/power/qcom-charger/smb-reg.h
index 2aed4cf294a2..c2a2b0c86d73 100644
--- a/drivers/power/qcom-charger/smb-reg.h
+++ b/drivers/power/qcom-charger/smb-reg.h
@@ -705,9 +705,6 @@ enum {
#define WIPWR_RANGE_STATUS_REG (DCIN_BASE + 0x08)
#define WIPWR_RANGE_STATUS_MASK GENMASK(4, 0)
-#define DC_INT_RT_STS_REG (DCIN_BASE + 0x10)
-#define DCIN_PLUGIN_RT_STS_BIT BIT(4)
-
/* DCIN Interrupt Bits */
#define WIPWR_VOLTAGE_RANGE_RT_STS_BIT BIT(7)
#define DCIN_ICL_CHANGE_RT_STS_BIT BIT(6)
@@ -905,6 +902,7 @@ enum {
#define MISC_CFG_REG (MISC_BASE + 0x52)
#define GSM_PA_ON_ADJ_SEL_BIT BIT(0)
+#define TCC_DEBOUNCE_20MS_BIT BIT(5)
#define SNARL_BARK_BITE_WD_CFG_REG (MISC_BASE + 0x53)
#define BITE_WDOG_DISABLE_CHARGING_CFG_BIT BIT(7)
diff --git a/drivers/power/qcom-charger/smb138x-charger.c b/drivers/power/qcom-charger/smb138x-charger.c
index 9a87ff5fb081..9dc528a6bb45 100644
--- a/drivers/power/qcom-charger/smb138x-charger.c
+++ b/drivers/power/qcom-charger/smb138x-charger.c
@@ -397,6 +397,7 @@ static int smb138x_init_batt_psy(struct smb138x *chip)
*****************************/
static enum power_supply_property smb138x_parallel_props[] = {
+ POWER_SUPPLY_PROP_CHARGE_TYPE,
POWER_SUPPLY_PROP_CHARGING_ENABLED,
POWER_SUPPLY_PROP_PIN_ENABLED,
POWER_SUPPLY_PROP_INPUT_SUSPEND,
@@ -417,6 +418,9 @@ static int smb138x_parallel_get_prop(struct power_supply *psy,
u8 temp;
switch (prop) {
+ case POWER_SUPPLY_PROP_CHARGE_TYPE:
+ rc = smblib_get_prop_batt_charge_type(chg, val);
+ break;
case POWER_SUPPLY_PROP_CHARGING_ENABLED:
rc = smblib_read(chg, BATTERY_CHARGER_STATUS_5_REG,
&temp);
diff --git a/drivers/regulator/qpnp-labibb-regulator.c b/drivers/regulator/qpnp-labibb-regulator.c
index 2e41401f8580..3d0be1f8a5b5 100644
--- a/drivers/regulator/qpnp-labibb-regulator.c
+++ b/drivers/regulator/qpnp-labibb-regulator.c
@@ -32,6 +32,7 @@
#define QPNP_LABIBB_REGULATOR_DRIVER_NAME "qcom,qpnp-labibb-regulator"
+#define REG_REVISION_2 0x01
#define REG_PERPH_TYPE 0x04
#define QPNP_LAB_TYPE 0x24
@@ -60,6 +61,7 @@
#define REG_LAB_PRECHARGE_CTL 0x5E
#define REG_LAB_SOFT_START_CTL 0x5F
#define REG_LAB_SPARE_CTL 0x60
+#define REG_LAB_PFM_CTL 0x62
/* LAB register bits definitions */
@@ -91,9 +93,9 @@
#define LAB_IBB_EN_RDY_EN BIT(7)
/* REG_LAB_CURRENT_LIMIT */
-#define LAB_CURRENT_LIMIT_BITS 3
-#define LAB_CURRENT_LIMIT_MASK ((1 << LAB_CURRENT_LIMIT_BITS) - 1)
-#define LAB_CURRENT_LIMIT_EN BIT(7)
+#define LAB_CURRENT_LIMIT_MASK GENMASK(2, 0)
+#define LAB_CURRENT_LIMIT_EN_BIT BIT(7)
+#define LAB_OVERRIDE_CURRENT_MAX_BIT BIT(3)
/* REG_LAB_CURRENT_SENSE */
#define LAB_CURRENT_SENSE_GAIN_BITS 2
@@ -129,6 +131,9 @@
#define LAB_SPARE_TOUCH_WAKE_BIT BIT(3)
#define LAB_SPARE_DISABLE_SCP_BIT BIT(0)
+/* REG_LAB_PFM_CTL */
+#define LAB_PFM_EN_BIT BIT(7)
+
/* IBB register offset definitions */
#define REG_IBB_REVISION4 0x03
#define REG_IBB_STATUS1 0x08
@@ -253,12 +258,6 @@
#define SWIRE_DEFAULT_2ND_CMD_DLY_MS 20
#define SWIRE_DEFAULT_IBB_PS_ENABLE_DLY_MS 200
-enum pmic_subtype {
- PMI8994 = 10,
- PMI8950 = 17,
- PMI8996 = 19,
-};
-
/**
* enum qpnp_labibb_mode - working mode of LAB/IBB regulators
* %QPNP_LABIBB_LCD_MODE: configure LAB and IBB regulators
@@ -350,6 +349,10 @@ static const int lab_current_limit_plan[] = {
400,
600,
800,
+ 1000,
+ 1200,
+ 1400,
+ 1600,
};
static const char * const lab_current_sense_plan[] = {
@@ -477,6 +480,8 @@ struct qpnp_labibb {
struct pmic_revid_data *pmic_rev_id;
u16 lab_base;
u16 ibb_base;
+ u8 lab_dig_major;
+ u8 ibb_dig_major;
struct lab_regulator lab_vreg;
struct ibb_regulator ibb_vreg;
enum qpnp_labibb_mode mode;
@@ -487,6 +492,7 @@ struct qpnp_labibb {
bool swire_control;
bool ttw_force_lab_on;
bool skip_2nd_swire_cmd;
+ bool pfm_enable;
u32 swire_2nd_cmd_delay;
u32 swire_ibb_ps_enable_delay;
};
@@ -539,60 +545,58 @@ static struct settings lab_settings[LAB_SETTINGS_MAX] = {
SETTING(LAB_RDSON_MNGMNT, false),
};
-static int
-qpnp_labibb_read(struct qpnp_labibb *labibb, u8 *val,
- u16 base, int count)
+static int qpnp_labibb_read(struct qpnp_labibb *labibb, u8 *val, u16 address,
+ int count)
{
int rc = 0;
struct platform_device *pdev = labibb->pdev;
- if (base == 0) {
- pr_err("base cannot be zero base=0x%02x sid=0x%02x rc=%d\n",
- base, to_spmi_device(pdev->dev.parent)->usid, rc);
+ if (address == 0) {
+ pr_err("address cannot be zero address=0x%02x sid=0x%02x rc=%d\n",
+ address, to_spmi_device(pdev->dev.parent)->usid, rc);
return -EINVAL;
}
- rc = regmap_bulk_read(labibb->regmap, base, val, count);
+ rc = regmap_bulk_read(labibb->regmap, address, val, count);
if (rc) {
- pr_err("SPMI read failed base=0x%02x sid=0x%02x rc=%d\n", base,
- to_spmi_device(pdev->dev.parent)->usid, rc);
+ pr_err("SPMI read failed address=0x%02x sid=0x%02x rc=%d\n",
+ address, to_spmi_device(pdev->dev.parent)->usid, rc);
return rc;
}
+
return 0;
}
-static int
-qpnp_labibb_write(struct qpnp_labibb *labibb, u16 base,
- u8 *val, int count)
+static int qpnp_labibb_write(struct qpnp_labibb *labibb, u16 address, u8 *val,
+ int count)
{
int rc = 0;
struct platform_device *pdev = labibb->pdev;
- if (base == 0) {
- pr_err("base cannot be zero base=0x%02x sid=0x%02x rc=%d\n",
- base, to_spmi_device(pdev->dev.parent)->usid, rc);
+ if (address == 0) {
+ pr_err("address cannot be zero address=0x%02x sid=0x%02x rc=%d\n",
+ address, to_spmi_device(pdev->dev.parent)->usid, rc);
return -EINVAL;
}
- rc = regmap_bulk_write(labibb->regmap, base, val, count);
+ rc = regmap_bulk_write(labibb->regmap, address, val, count);
if (rc) {
- pr_err("write failed base=0x%02x sid=0x%02x rc=%d\n",
- base, to_spmi_device(pdev->dev.parent)->usid, rc);
+ pr_err("write failed address=0x%02x sid=0x%02x rc=%d\n",
+ address, to_spmi_device(pdev->dev.parent)->usid, rc);
return rc;
}
return 0;
}
-static int
-qpnp_labibb_masked_write(struct qpnp_labibb *labibb, u16 base,
- u8 mask, u8 val)
+static int qpnp_labibb_masked_write(struct qpnp_labibb *labibb, u16 address,
+ u8 mask, u8 val)
{
int rc;
- rc = regmap_update_bits(labibb->regmap, base, mask, val);
+ rc = regmap_update_bits(labibb->regmap, address, mask, val);
if (rc) {
- pr_err("spmi write failed: addr=%03X, rc=%d\n", base, rc);
+ pr_err("spmi write failed: addr=%03X, rc=%d\n", address, rc);
return rc;
}
@@ -709,18 +713,24 @@ static int qpnp_lab_dt_init(struct qpnp_labibb *labibb,
u8 i, val;
u32 tmp;
- if (labibb->mode == QPNP_LABIBB_LCD_MODE)
- val = REG_LAB_IBB_LCD_MODE;
- else
- val = REG_LAB_IBB_AMOLED_MODE;
+ /*
+ * Do not configure LCD_AMOLED_SEL for pmicobalt as it will be done by
+ * GPIO selector.
+ */
+ if (labibb->pmic_rev_id->pmic_subtype != PMICOBALT_SUBTYPE) {
+ if (labibb->mode == QPNP_LABIBB_LCD_MODE)
+ val = REG_LAB_IBB_LCD_MODE;
+ else
+ val = REG_LAB_IBB_AMOLED_MODE;
- rc = qpnp_labibb_sec_write(labibb, labibb->lab_base,
- REG_LAB_LCD_AMOLED_SEL, &val, 1);
+ rc = qpnp_labibb_sec_write(labibb, labibb->lab_base,
+ REG_LAB_LCD_AMOLED_SEL, &val, 1);
- if (rc) {
- pr_err("qpnp_lab_sec_write register %x failed rc = %d\n",
- REG_LAB_LCD_AMOLED_SEL, rc);
- return rc;
+ if (rc) {
+ pr_err("qpnp_lab_sec_write register %x failed rc = %d\n",
+ REG_LAB_LCD_AMOLED_SEL, rc);
+ return rc;
+ }
}
val = 0;
@@ -785,7 +795,7 @@ static int qpnp_lab_dt_init(struct qpnp_labibb *labibb,
if (of_property_read_bool(of_node,
"qcom,qpnp-lab-limit-max-current-enable"))
- val |= LAB_CURRENT_LIMIT_EN;
+ val |= LAB_CURRENT_LIMIT_EN_BIT;
rc = qpnp_labibb_write(labibb, labibb->lab_base +
REG_LAB_CURRENT_LIMIT, &val, 1);
@@ -938,6 +948,88 @@ static int qpnp_lab_dt_init(struct qpnp_labibb *labibb,
return rc;
}
+#define LAB_CURRENT_MAX_1600MA 0x7
+#define LAB_CURRENT_MAX_400MA 0x1
+static int qpnp_lab_pfm_disable(struct qpnp_labibb *labibb)
+{
+ int rc = 0;
+ u8 val, mask;
+
+ mutex_lock(&(labibb->lab_vreg.lab_mutex));
+ if (!labibb->pfm_enable) {
+ pr_debug("PFM already disabled\n");
+ goto out;
+ }
+
+ val = 0;
+ mask = LAB_PFM_EN_BIT;
+ rc = qpnp_labibb_masked_write(labibb, labibb->lab_base +
+ REG_LAB_PFM_CTL, mask, val);
+ if (rc < 0) {
+ pr_err("Write register %x failed rc = %d\n",
+ REG_LAB_PFM_CTL, rc);
+ goto out;
+ }
+
+ val = LAB_CURRENT_MAX_1600MA;
+ mask = LAB_OVERRIDE_CURRENT_MAX_BIT | LAB_CURRENT_LIMIT_MASK;
+ rc = qpnp_labibb_masked_write(labibb, labibb->lab_base +
+ REG_LAB_CURRENT_LIMIT, mask, val);
+ if (rc < 0) {
+ pr_err("Write register %x failed rc = %d\n",
+ REG_LAB_CURRENT_LIMIT, rc);
+ goto out;
+ }
+
+ labibb->pfm_enable = false;
+out:
+ mutex_unlock(&(labibb->lab_vreg.lab_mutex));
+ return rc;
+}
+
+static int qpnp_lab_pfm_enable(struct qpnp_labibb *labibb)
+{
+ int rc = 0;
+ u8 val, mask;
+
+ mutex_lock(&(labibb->lab_vreg.lab_mutex));
+ if (labibb->pfm_enable) {
+ pr_debug("PFM already enabled\n");
+ goto out;
+ }
+
+ /* Wait for ~100uS */
+ usleep_range(100, 105);
+
+ val = LAB_OVERRIDE_CURRENT_MAX_BIT | LAB_CURRENT_MAX_400MA;
+ mask = LAB_OVERRIDE_CURRENT_MAX_BIT | LAB_CURRENT_LIMIT_MASK;
+ rc = qpnp_labibb_masked_write(labibb, labibb->lab_base +
+ REG_LAB_CURRENT_LIMIT, mask, val);
+ if (rc < 0) {
+ pr_err("Write register %x failed rc = %d\n",
+ REG_LAB_CURRENT_LIMIT, rc);
+ goto out;
+ }
+
+ /* Wait for ~100uS */
+ usleep_range(100, 105);
+
+ val = LAB_PFM_EN_BIT;
+ mask = LAB_PFM_EN_BIT;
+ rc = qpnp_labibb_masked_write(labibb, labibb->lab_base +
+ REG_LAB_PFM_CTL, mask, val);
+ if (rc < 0) {
+ pr_err("Write register %x failed rc = %d\n",
+ REG_LAB_PFM_CTL, rc);
+ goto out;
+ }
+
+ labibb->pfm_enable = true;
+out:
+ mutex_unlock(&(labibb->lab_vreg.lab_mutex));
+ return rc;
+}
+
static int qpnp_labibb_restore_settings(struct qpnp_labibb *labibb)
{
int rc, i;
@@ -1172,7 +1264,7 @@ static int qpnp_labibb_regulator_ttw_mode_enter(struct qpnp_labibb *labibb)
}
val = LAB_SPARE_DISABLE_SCP_BIT;
- if (labibb->pmic_rev_id->pmic_subtype != PMI8950)
+ if (labibb->pmic_rev_id->pmic_subtype != PMI8950_SUBTYPE)
val |= LAB_SPARE_TOUCH_WAKE_BIT;
rc = qpnp_labibb_write(labibb, labibb->lab_base +
REG_LAB_SPARE_CTL, &val, 1);
@@ -1199,10 +1291,10 @@ static int qpnp_labibb_regulator_ttw_mode_enter(struct qpnp_labibb *labibb)
}
switch (labibb->pmic_rev_id->pmic_subtype) {
- case PMI8996:
+ case PMI8996_SUBTYPE:
rc = qpnp_labibb_ttw_enter_ibb_pmi8996(labibb);
break;
- case PMI8950:
+ case PMI8950_SUBTYPE:
rc = qpnp_labibb_ttw_enter_ibb_pmi8950(labibb);
break;
}
@@ -1282,9 +1374,9 @@ static int qpnp_labibb_regulator_ttw_mode_exit(struct qpnp_labibb *labibb)
}
switch (labibb->pmic_rev_id->pmic_subtype) {
- case PMI8996:
- case PMI8994:
- case PMI8950:
+ case PMI8996_SUBTYPE:
+ case PMI8994_SUBTYPE:
+ case PMI8950_SUBTYPE:
rc = qpnp_labibb_ttw_exit_ibb_common(labibb);
break;
}
@@ -1437,6 +1529,15 @@ static int qpnp_labibb_regulator_disable(struct qpnp_labibb *labibb)
return -EINVAL;
}
+ if (labibb->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE &&
+ labibb->mode == QPNP_LABIBB_LCD_MODE) {
+ rc = qpnp_lab_pfm_disable(labibb);
+ if (rc < 0) {
+ pr_err("Error in disabling PFM, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
labibb->lab_vreg.vreg_enabled = 0;
labibb->ibb_vreg.vreg_enabled = 0;
@@ -1646,9 +1747,17 @@ static irqreturn_t lab_vreg_ok_handler(int irq, void *_labibb)
struct qpnp_labibb *labibb = _labibb;
int rc;
- rc = qpnp_skip_swire_command(labibb);
- if (rc)
- pr_err("Failed in 'qpnp_skip_swire_command' rc=%d\n", rc);
+ if (labibb->skip_2nd_swire_cmd && labibb->lab_dig_major < 2) {
+ rc = qpnp_skip_swire_command(labibb);
+ if (rc < 0)
+ pr_err("Failed in 'qpnp_skip_swire_command' rc=%d\n",
+ rc);
+ } else if (labibb->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE &&
+ labibb->mode == QPNP_LABIBB_LCD_MODE) {
+ rc = qpnp_lab_pfm_enable(labibb);
+ if (rc < 0)
+ pr_err("Failed to config PFM, rc=%d\n", rc);
+ }
return IRQ_HANDLED;
}
@@ -1663,6 +1772,23 @@ static int qpnp_lab_regulator_get_voltage(struct regulator_dev *rdev)
return labibb->lab_vreg.curr_volt;
}
+static bool is_lab_vreg_ok_irq_available(struct qpnp_labibb *labibb)
+{
+ /*
+ * LAB VREG_OK interrupt is used only to skip 2nd SWIRE command in
+ * dig_major < 2 targets. For pmicobalt, it is used to enable PFM in
+ * LCD mode.
+ */
+ if (labibb->skip_2nd_swire_cmd && labibb->lab_dig_major < 2)
+ return true;
+
+ if (labibb->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE &&
+ labibb->mode == QPNP_LABIBB_LCD_MODE)
+ return true;
+
+ return false;
+}
+
static struct regulator_ops qpnp_lab_ops = {
.enable = qpnp_lab_regulator_enable,
.disable = qpnp_lab_regulator_disable,
@@ -1784,16 +1910,16 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb,
}
if (of_find_property(of_node,
- "qpnp,qpnp-lab-current-sense", NULL)) {
+ "qcom,qpnp-lab-current-sense", NULL)) {
config_current_sense = true;
rc = of_property_read_string(of_node,
- "qpnp,qpnp-lab-current-sense",
+ "qcom,qpnp-lab-current-sense",
&current_sense_str);
if (!rc) {
val = qpnp_labibb_get_matching_idx(
current_sense_str);
} else {
- pr_err("qpnp,qpnp-lab-current-sense configured incorrectly rc = %d\n",
+ pr_err("qcom,qpnp-lab-current-sense configured incorrectly rc = %d\n",
rc);
return rc;
}
@@ -1811,19 +1937,6 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb,
}
}
- if (labibb->skip_2nd_swire_cmd) {
- rc = devm_request_threaded_irq(labibb->dev,
- labibb->lab_vreg.lab_vreg_ok_irq, NULL,
- lab_vreg_ok_handler,
- IRQF_ONESHOT | IRQF_TRIGGER_RISING,
- "lab-vreg-ok", labibb);
- if (rc) {
- pr_err("Failed to register 'lab-vreg-ok' irq rc=%d\n",
- rc);
- return rc;
- }
- }
-
val = (labibb->standalone) ? 0 : LAB_IBB_EN_RDY_EN;
rc = qpnp_labibb_sec_write(labibb, labibb->lab_base,
REG_LAB_IBB_EN_RDY, &val, 1);
@@ -1901,6 +2014,19 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb,
labibb->lab_vreg.vreg_enabled = 1;
}
+ if (is_lab_vreg_ok_irq_available(labibb)) {
+ rc = devm_request_threaded_irq(labibb->dev,
+ labibb->lab_vreg.lab_vreg_ok_irq, NULL,
+ lab_vreg_ok_handler,
+ IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+ "lab-vreg-ok", labibb);
+ if (rc) {
+ pr_err("Failed to register 'lab-vreg-ok' irq rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
+
rc = qpnp_labibb_read(labibb, &val,
labibb->lab_base + REG_LAB_MODULE_RDY, 1);
if (rc) {
@@ -1955,7 +2081,6 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb,
return -EINVAL;
}
- mutex_init(&(labibb->lab_vreg.lab_mutex));
return 0;
}
@@ -1966,18 +2091,37 @@ static int qpnp_ibb_dt_init(struct qpnp_labibb *labibb,
u32 i, tmp;
u8 val;
- if (labibb->mode == QPNP_LABIBB_LCD_MODE)
- val = REG_LAB_IBB_LCD_MODE;
- else
- val = REG_LAB_IBB_AMOLED_MODE;
+ /*
+ * Do not configure LCD_AMOLED_SEL for pmicobalt as it will be done by
+ * GPIO selector. Override the labibb->mode with what was configured
+ * by the bootloader.
+ */
+ if (labibb->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE) {
+ rc = qpnp_labibb_read(labibb, &val,
+ labibb->ibb_base + REG_IBB_LCD_AMOLED_SEL, 1);
+ if (rc) {
+ pr_err("qpnp_labibb_read register %x failed rc = %d\n",
+ REG_IBB_LCD_AMOLED_SEL, rc);
+ return rc;
+ }
- rc = qpnp_labibb_sec_write(labibb, labibb->ibb_base,
- REG_LAB_LCD_AMOLED_SEL, &val, 1);
+ if (val == REG_LAB_IBB_AMOLED_MODE)
+ labibb->mode = QPNP_LABIBB_AMOLED_MODE;
+ else
+ labibb->mode = QPNP_LABIBB_LCD_MODE;
+ } else {
+ if (labibb->mode == QPNP_LABIBB_LCD_MODE)
+ val = REG_LAB_IBB_LCD_MODE;
+ else
+ val = REG_LAB_IBB_AMOLED_MODE;
- if (rc) {
- pr_err("qpnp_labibb_sec_write register %x failed rc = %d\n",
- REG_IBB_LCD_AMOLED_SEL, rc);
- return rc;
+ rc = qpnp_labibb_sec_write(labibb, labibb->ibb_base,
+ REG_LAB_LCD_AMOLED_SEL, &val, 1);
+ if (rc) {
+ pr_err("qpnp_labibb_sec_write register %x failed rc = %d\n",
+ REG_IBB_LCD_AMOLED_SEL, rc);
+ return rc;
+ }
}
rc = of_property_read_u32(of_node, "qcom,qpnp-ibb-lab-pwrdn-delay",
@@ -2482,6 +2626,13 @@ static int register_qpnp_ibb_regulator(struct qpnp_labibb *labibb,
return rc;
}
+ /*
+ * For pmicobalt, override swire_control with what was configured
+ * before by the bootloader.
+ */
+ if (labibb->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE)
+ labibb->swire_control = val & IBB_ENABLE_CTL_SWIRE_RDY;
+
if (ibb_enable_ctl &
(IBB_ENABLE_CTL_SWIRE_RDY | IBB_ENABLE_CTL_MODULE_EN)) {
/* SWIRE_RDY or IBB_MODULE_EN enabled */
@@ -2659,14 +2810,13 @@ static int register_qpnp_ibb_regulator(struct qpnp_labibb *labibb,
return -EINVAL;
}
- mutex_init(&(labibb->ibb_vreg.ibb_mutex));
return 0;
}
static int qpnp_lab_register_irq(struct device_node *child,
struct qpnp_labibb *labibb)
{
- if (labibb->skip_2nd_swire_cmd) {
+ if (is_lab_vreg_ok_irq_available(labibb)) {
labibb->lab_vreg.lab_vreg_ok_irq =
of_irq_get_byname(child, "lab-vreg-ok");
if (labibb->lab_vreg.lab_vreg_ok_irq < 0) {
@@ -2684,7 +2834,7 @@ static int qpnp_labibb_check_ttw_supported(struct qpnp_labibb *labibb)
u8 val;
switch (labibb->pmic_rev_id->pmic_subtype) {
- case PMI8996:
+ case PMI8996_SUBTYPE:
rc = qpnp_labibb_read(labibb, &val,
labibb->ibb_base + REG_IBB_REVISION4, 1);
if (rc) {
@@ -2702,7 +2852,7 @@ static int qpnp_labibb_check_ttw_supported(struct qpnp_labibb *labibb)
/* FORCE_LAB_ON in TTW is not required for PMI8996 */
labibb->ttw_force_lab_on = false;
break;
- case PMI8950:
+ case PMI8950_SUBTYPE:
/* TTW supported for all revisions */
break;
default:
@@ -2721,7 +2871,7 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
unsigned int base;
struct device_node *child, *revid_dev_node;
const char *mode_name;
- u8 type;
+ u8 type, revision;
int rc = 0;
labibb = devm_kzalloc(&pdev->dev,
@@ -2739,6 +2889,9 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
labibb->dev = &(pdev->dev);
labibb->pdev = pdev;
+ mutex_init(&(labibb->lab_vreg.lab_mutex));
+ mutex_init(&(labibb->ibb_vreg.ibb_mutex));
+
revid_dev_node = of_parse_phandle(labibb->dev->of_node,
"qcom,pmic-revid", 0);
if (!revid_dev_node) {
@@ -2753,19 +2906,19 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
}
rc = of_property_read_string(labibb->dev->of_node,
- "qpnp,qpnp-labibb-mode", &mode_name);
+ "qcom,qpnp-labibb-mode", &mode_name);
if (!rc) {
if (strcmp("lcd", mode_name) == 0) {
labibb->mode = QPNP_LABIBB_LCD_MODE;
} else if (strcmp("amoled", mode_name) == 0) {
labibb->mode = QPNP_LABIBB_AMOLED_MODE;
} else {
- pr_err("Invalid device property in qpnp,qpnp-labibb-mode: %s\n",
+ pr_err("Invalid device property in qcom,qpnp-labibb-mode: %s\n",
mode_name);
return -EINVAL;
}
} else {
- pr_err("qpnp_labibb: qpnp,qpnp-labibb-mode is missing.\n");
+ pr_err("qpnp_labibb: qcom,qpnp-labibb-mode is missing.\n");
return rc;
}
@@ -2783,15 +2936,17 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
labibb->dev->of_node, "qcom,labibb-ttw-force-lab-on");
labibb->swire_control = of_property_read_bool(labibb->dev->of_node,
- "qpnp,swire-control");
+ "qcom,swire-control");
if (labibb->swire_control && labibb->mode != QPNP_LABIBB_AMOLED_MODE) {
pr_err("Invalid mode for SWIRE control\n");
return -EINVAL;
}
+
if (labibb->swire_control) {
labibb->skip_2nd_swire_cmd =
of_property_read_bool(labibb->dev->of_node,
"qcom,skip-2nd-swire-cmd");
+
rc = of_property_read_u32(labibb->dev->of_node,
"qcom,swire-2nd-cmd-delay",
&labibb->swire_2nd_cmd_delay);
@@ -2811,6 +2966,7 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
pr_err("no child nodes\n");
return -ENXIO;
}
+
for_each_available_child_of_node(pdev->dev.of_node, child) {
rc = of_property_read_u32(child, "reg", &base);
if (rc < 0) {
@@ -2820,6 +2976,13 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
return rc;
}
+ rc = qpnp_labibb_read(labibb, &revision, base + REG_REVISION_2,
+ 1);
+ if (rc) {
+ pr_err("Reading REVISION_2 failed rc=%d\n", rc);
+ goto fail_registration;
+ }
+
rc = qpnp_labibb_read(labibb, &type,
base + REG_PERPH_TYPE, 1);
if (rc) {
@@ -2830,6 +2993,7 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
switch (type) {
case QPNP_LAB_TYPE:
labibb->lab_base = base;
+ labibb->lab_dig_major = revision;
rc = qpnp_lab_register_irq(child, labibb);
if (rc) {
pr_err("Failed to register LAB IRQ rc=%d\n",
@@ -2843,6 +3007,7 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
case QPNP_IBB_TYPE:
labibb->ibb_base = base;
+ labibb->ibb_dig_major = revision;
rc = register_qpnp_ibb_regulator(labibb, child);
if (rc)
goto fail_registration;
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 873b4615d4a9..603cbe65825b 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -412,8 +412,9 @@ static int ufs_qcom_hce_enable_notify(struct ufs_hba *hba,
/**
* Returns zero for success and non-zero in case of a failure
*/
-static int ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear,
- u32 hs, u32 rate, bool update_link_startup_timer)
+static int __ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear,
+ u32 hs, u32 rate, bool update_link_startup_timer,
+ bool is_pre_scale_up)
{
int ret = 0;
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
@@ -460,8 +461,12 @@ static int ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear,
}
list_for_each_entry(clki, &hba->clk_list_head, list) {
- if (!strcmp(clki->name, "core_clk"))
- core_clk_rate = clk_get_rate(clki->clk);
+ if (!strcmp(clki->name, "core_clk")) {
+ if (is_pre_scale_up)
+ core_clk_rate = clki->max_freq;
+ else
+ core_clk_rate = clk_get_rate(clki->clk);
+ }
}
/* If frequency is smaller than 1MHz, set to 1MHz */
@@ -558,6 +563,13 @@ out:
return ret;
}
+static int ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear,
+ u32 hs, u32 rate, bool update_link_startup_timer)
+{
+ return __ufs_qcom_cfg_timers(hba, gear, hs, rate,
+ update_link_startup_timer, false);
+}
+
static int ufs_qcom_link_startup_pre_change(struct ufs_hba *hba)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
@@ -2160,61 +2172,49 @@ out:
static int ufs_qcom_clk_scale_up_pre_change(struct ufs_hba *hba)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+ struct ufs_pa_layer_attr *attr = &host->dev_req_params;
+ int err = 0;
if (!ufs_qcom_cap_qunipro(host))
- return 0;
-
- return ufs_qcom_configure_lpm(hba, false);
-}
+ goto out;
-static int ufs_qcom_clk_scale_up_post_change(struct ufs_hba *hba)
-{
- struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+ err = ufs_qcom_configure_lpm(hba, false);
+ if (err)
+ goto out;
- if (!ufs_qcom_cap_qunipro(host))
- return 0;
+ if (attr)
+ __ufs_qcom_cfg_timers(hba, attr->gear_rx, attr->pwr_rx,
+ attr->hs_rate, false, true);
/* set unipro core clock cycles to 150 and clear clock divider */
- return ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba, 150);
+ err = ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba, 150);
+out:
+ return err;
}
static int ufs_qcom_clk_scale_down_pre_change(struct ufs_hba *hba)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
- u32 core_clk_ctrl_reg;
- int err = 0;
if (!ufs_qcom_cap_qunipro(host))
- goto out;
-
- err = ufs_qcom_configure_lpm(hba, true);
- if (err)
- goto out;
-
- err = ufshcd_dme_get(hba,
- UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
- &core_clk_ctrl_reg);
+ return 0;
- /* make sure CORE_CLK_DIV_EN is cleared */
- if (!err &&
- (core_clk_ctrl_reg & DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT)) {
- core_clk_ctrl_reg &= ~DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT;
- err = ufshcd_dme_set(hba,
- UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
- core_clk_ctrl_reg);
- }
-out:
- return err;
+ return ufs_qcom_configure_lpm(hba, true);
}
static int ufs_qcom_clk_scale_down_post_change(struct ufs_hba *hba)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+ struct ufs_pa_layer_attr *attr = &host->dev_req_params;
int err = 0;
if (!ufs_qcom_cap_qunipro(host))
return 0;
+ if (attr)
+ ufs_qcom_cfg_timers(hba, attr->gear_rx, attr->pwr_rx,
+ attr->hs_rate, false);
+
if (ufs_qcom_cap_svs2(host))
/*
* For SVS2 set unipro core clock cycles to 37 and
@@ -2235,7 +2235,6 @@ static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba,
bool scale_up, enum ufs_notify_change_status status)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
- struct ufs_pa_layer_attr *dev_req_params = &host->dev_req_params;
int err = 0;
switch (status) {
@@ -2246,19 +2245,9 @@ static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba,
err = ufs_qcom_clk_scale_down_pre_change(hba);
break;
case POST_CHANGE:
- if (scale_up)
- err = ufs_qcom_clk_scale_up_post_change(hba);
- else
+ if (!scale_up)
err = ufs_qcom_clk_scale_down_post_change(hba);
- if (err || !dev_req_params)
- goto out;
-
- ufs_qcom_cfg_timers(hba,
- dev_req_params->gear_rx,
- dev_req_params->pwr_rx,
- dev_req_params->hs_rate,
- false);
ufs_qcom_update_bus_bw_vote(host);
break;
default:
@@ -2267,7 +2256,6 @@ static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba,
break;
}
-out:
return err;
}
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 862d56e78086..67e1636c25ec 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2633,6 +2633,65 @@ static inline u16 ufshcd_upiu_wlun_to_scsi_wlun(u8 upiu_wlun_id)
}
/**
+ * ufshcd_get_write_lock - synchronize between shutdown, scaling &
+ * arrival of requests
+ * @hba: ufs host
+ *
+ * Lock is predominantly held by shutdown context thus, ensuring
+ * that no requests from any other context may sneak through.
+ */
+static void ufshcd_get_write_lock(struct ufs_hba *hba)
+{
+ down_write(&hba->lock);
+ hba->issuing_task = current;
+}
+
+/**
+ * ufshcd_get_read_lock - synchronize between shutdown, scaling &
+ * arrival of requests
+ * @hba: ufs host
+ *
+ * Returns 1 if acquired, < 0 on contention
+ *
+ * After shutdown's initiated, allow requests only from shutdown
+ * context. The sync between scaling & issue is maintained
+ * as is and this restructuring syncs shutdown with these too.
+ */
+static int ufshcd_get_read_lock(struct ufs_hba *hba)
+{
+ int err = 0;
+
+ err = down_read_trylock(&hba->lock);
+ if (err > 0)
+ goto out;
+ if (hba->issuing_task == current)
+ return 0;
+ else if (!ufshcd_is_shutdown_ongoing(hba))
+ return -EAGAIN;
+ else
+ return -EPERM;
+
+out:
+ hba->issuing_task = current;
+ return err;
+}
+
+/**
+ * ufshcd_put_read_lock - synchronize between shutdown, scaling &
+ * arrival of requests
+ * @hba: ufs host
+ *
+ * Returns none
+ */
+static inline void ufshcd_put_read_lock(struct ufs_hba *hba)
+{
+ if (!ufshcd_is_shutdown_ongoing(hba)) {
+ hba->issuing_task = NULL;
+ up_read(&hba->lock);
+ }
+}
+
+/**
* ufshcd_queuecommand - main entry point for SCSI requests
* @cmd: command from SCSI Midlayer
* @done: call back function
@@ -2657,8 +2716,16 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
BUG();
}
- if (!down_read_trylock(&hba->clk_scaling_lock))
- return SCSI_MLQUEUE_HOST_BUSY;
+ err = ufshcd_get_read_lock(hba);
+ if (unlikely(err < 0)) {
+ if (err == -EPERM) {
+ set_host_byte(cmd, DID_ERROR);
+ cmd->scsi_done(cmd);
+ return 0;
+ }
+ if (err == -EAGAIN)
+ return SCSI_MLQUEUE_HOST_BUSY;
+ }
spin_lock_irqsave(hba->host->host_lock, flags);
@@ -2798,7 +2865,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
out_unlock:
spin_unlock_irqrestore(hba->host->host_lock, flags);
out:
- up_read(&hba->clk_scaling_lock);
+ ufshcd_put_read_lock(hba);
return err;
}
@@ -2990,7 +3057,12 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
struct completion wait;
unsigned long flags;
- down_read(&hba->clk_scaling_lock);
+ /*
+ * May get invoked from shutdown and IOCTL contexts.
+ * In shutdown context, it comes in with lock acquired.
+ */
+ if (!ufshcd_is_shutdown_ongoing(hba))
+ down_read(&hba->lock);
/*
* Get free slot, sleep if slots are unavailable.
@@ -3023,7 +3095,8 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
out_put_tag:
ufshcd_put_dev_cmd_tag(hba, tag);
wake_up(&hba->dev_cmd.tag_wq);
- up_read(&hba->clk_scaling_lock);
+ if (!ufshcd_is_shutdown_ongoing(hba))
+ up_read(&hba->lock);
return err;
}
@@ -4132,7 +4205,13 @@ static int __ufshcd_uic_hibern8_enter(struct ufs_hba *hba)
trace_ufshcd_profile_hibern8(dev_name(hba->dev), "enter",
ktime_to_us(ktime_sub(ktime_get(), start)), ret);
- if (ret) {
+ /*
+ * Do full reinit if enter failed or if LINERESET was detected during
+ * Hibern8 operation. After LINERESET, link moves to default PWM-G1
+ * mode hence full reinit is required to move link to HS speeds.
+ */
+ if (ret || hba->full_init_linereset) {
+ hba->full_init_linereset = false;
ufshcd_update_error_stats(hba, UFS_ERR_HIBERN8_ENTER);
dev_err(hba->dev, "%s: hibern8 enter failed. ret = %d",
__func__, ret);
@@ -4175,8 +4254,13 @@ int ufshcd_uic_hibern8_exit(struct ufs_hba *hba)
ret = ufshcd_uic_pwr_ctrl(hba, &uic_cmd);
trace_ufshcd_profile_hibern8(dev_name(hba->dev), "exit",
ktime_to_us(ktime_sub(ktime_get(), start)), ret);
-
- if (ret) {
+ /*
+ * Do full reinit if exit failed or if LINERESET was detected during
+ * Hibern8 operation. After LINERESET, link moves to default PWM-G1
+ * mode hence full reinit is required to move link to HS speeds.
+ */
+ if (ret || hba->full_init_linereset) {
+ hba->full_init_linereset = false;
ufshcd_update_error_stats(hba, UFS_ERR_HIBERN8_EXIT);
dev_err(hba->dev, "%s: hibern8 exit failed. ret = %d",
__func__, ret);
@@ -5696,10 +5780,13 @@ static void ufshcd_err_handler(struct work_struct *work)
dev_err(hba->dev, "%s: saved_err 0x%x saved_uic_err 0x%x",
__func__, hba->saved_err, hba->saved_uic_err);
if (!hba->silence_err_logs) {
+ /* release lock as print host regs sleeps */
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
ufshcd_print_host_regs(hba);
ufshcd_print_host_state(hba);
ufshcd_print_pwr_info(hba);
ufshcd_print_tmrs(hba, hba->outstanding_tasks);
+ spin_lock_irqsave(hba->host->host_lock, flags);
}
}
@@ -5827,9 +5914,8 @@ static void ufshcd_update_uic_error(struct ufs_hba *hba)
/* PHY layer lane error */
reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER);
- /* Ignore LINERESET indication, as this is not an error */
if ((reg & UIC_PHY_ADAPTER_LAYER_ERROR) &&
- (reg & UIC_PHY_ADAPTER_LAYER_LANE_ERR_MASK)) {
+ (reg & UIC_PHY_ADAPTER_LAYER_ERROR_CODE_MASK)) {
/*
* To know whether this error is fatal or not, DB timeout
* must be checked but this error is handled separately.
@@ -5837,6 +5923,20 @@ static void ufshcd_update_uic_error(struct ufs_hba *hba)
dev_dbg(hba->dev, "%s: UIC Lane error reported, reg 0x%x\n",
__func__, reg);
ufshcd_update_uic_reg_hist(&hba->ufs_stats.pa_err, reg);
+
+ /* Don't ignore LINERESET indication during hibern8 operation */
+ if (reg & UIC_PHY_ADAPTER_LAYER_GENERIC_ERROR) {
+ struct uic_command *cmd = hba->active_uic_cmd;
+
+ if (cmd) {
+ if ((cmd->command == UIC_CMD_DME_HIBER_ENTER)
+ || (cmd->command == UIC_CMD_DME_HIBER_EXIT)) {
+ dev_err(hba->dev, "%s: LINERESET during hibern8, reg 0x%x\n",
+ __func__, reg);
+ hba->full_init_linereset = true;
+ }
+ }
+ }
}
/* PA_INIT_ERROR is fatal and needs UIC reset */
@@ -6908,11 +7008,6 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
if (ret)
goto out;
- /* Enable auto hibern8 if supported */
- if (ufshcd_is_auto_hibern8_supported(hba))
- ufshcd_set_auto_hibern8_timer(hba,
- hba->hibern8_on_idle.delay_ms);
-
/* Debug counters initialization */
ufshcd_clear_dbg_ufs_stats(hba);
/* set the default level for urgent bkops */
@@ -6979,6 +7074,13 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
if (ufshcd_scsi_add_wlus(hba))
goto out;
+ /* Enable auto hibern8 if supported, after full host and
+ * device initialization.
+ */
+ if (ufshcd_is_auto_hibern8_supported(hba))
+ ufshcd_set_auto_hibern8_timer(hba,
+ hba->hibern8_on_idle.delay_ms);
+
/* Initialize devfreq after UFS device is detected */
if (ufshcd_is_clkscaling_supported(hba)) {
memcpy(&hba->clk_scaling.saved_pwr_info.info,
@@ -8654,11 +8756,37 @@ static inline void ufshcd_add_sysfs_nodes(struct ufs_hba *hba)
*/
int ufshcd_shutdown(struct ufs_hba *hba)
{
- /*
- * TODO: This function should send the power down notification to
- * UFS device and then power off the UFS link. But we need to be sure
- * that there will not be any new UFS requests issued after this.
+ int ret = 0;
+
+ if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba))
+ goto out;
+
+ pm_runtime_get_sync(hba->dev);
+ ufshcd_hold_all(hba);
+ /**
+ * (1) Acquire the lock to stop any more requests
+ * (2) Set state to shutting down
+ * (3) Suspend clock scaling
+ * (4) Wait for all issued requests to complete
*/
+ ufshcd_get_write_lock(hba);
+ ufshcd_mark_shutdown_ongoing(hba);
+ ufshcd_scsi_block_requests(hba);
+ ufshcd_suspend_clkscaling(hba);
+ ret = ufshcd_wait_for_doorbell_clr(hba, U64_MAX);
+ if (ret)
+ dev_err(hba->dev, "%s: waiting for DB clear: failed: %d\n",
+ __func__, ret);
+ /* Requests may have errored out above, let it be handled */
+ flush_work(&hba->eh_work);
+ /* reqs issued from contexts other than shutdown will fail from now */
+ ufshcd_scsi_unblock_requests(hba);
+ ufshcd_release_all(hba);
+ ret = ufshcd_suspend(hba, UFS_SHUTDOWN_PM);
+out:
+ if (ret)
+ dev_err(hba->dev, "%s failed, err %d\n", __func__, ret);
+ /* allow force shutdown even in case of errors */
return 0;
}
EXPORT_SYMBOL(ufshcd_shutdown);
@@ -8843,10 +8971,10 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba)
* clock scaling is in progress
*/
ufshcd_scsi_block_requests(hba);
- down_write(&hba->clk_scaling_lock);
+ down_write(&hba->lock);
if (ufshcd_wait_for_doorbell_clr(hba, DOORBELL_CLR_TOUT_US)) {
ret = -EBUSY;
- up_write(&hba->clk_scaling_lock);
+ up_write(&hba->lock);
ufshcd_scsi_unblock_requests(hba);
}
@@ -8855,7 +8983,7 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba)
static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba)
{
- up_write(&hba->clk_scaling_lock);
+ up_write(&hba->lock);
ufshcd_scsi_unblock_requests(hba);
}
@@ -9038,6 +9166,10 @@ static void ufshcd_clk_scaling_resume_work(struct work_struct *work)
clk_scaling.resume_work);
unsigned long irq_flags;
+ /* Let's not resume scaling if shutdown is ongoing */
+ if (ufshcd_is_shutdown_ongoing(hba))
+ return;
+
spin_lock_irqsave(hba->host->host_lock, irq_flags);
if (!hba->clk_scaling.is_suspended) {
spin_unlock_irqrestore(hba->host->host_lock, irq_flags);
@@ -9250,7 +9382,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
/* Initialize mutex for device management commands */
mutex_init(&hba->dev_cmd.lock);
- init_rwsem(&hba->clk_scaling_lock);
+ init_rwsem(&hba->lock);
/* Initialize device management tag acquire wait queue */
init_waitqueue_head(&hba->dev_cmd.tag_wq);
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index c0714b7bea72..9f2b04c8ff82 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -895,15 +895,30 @@ struct ufs_hba {
enum bkops_status urgent_bkops_lvl;
bool is_urgent_bkops_lvl_checked;
- struct rw_semaphore clk_scaling_lock;
+ /* sync b/w diff contexts */
+ struct rw_semaphore lock;
+ struct task_struct *issuing_task;
+ unsigned long shutdown_in_prog;
struct reset_control *core_reset;
/* If set, don't gate device ref_clk during clock gating */
bool no_ref_clk_gating;
int scsi_block_reqs_cnt;
+
+ bool full_init_linereset;
};
+static inline void ufshcd_mark_shutdown_ongoing(struct ufs_hba *hba)
+{
+ set_bit(0, &hba->shutdown_in_prog);
+}
+
+static inline bool ufshcd_is_shutdown_ongoing(struct ufs_hba *hba)
+{
+ return !!(test_bit(0, &hba->shutdown_in_prog));
+}
+
/* Returns true if clocks can be gated. Otherwise false */
static inline bool ufshcd_is_clkgating_allowed(struct ufs_hba *hba)
{
diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h
index d65dad03bdd2..c0e4650a75ad 100644
--- a/drivers/scsi/ufs/ufshci.h
+++ b/drivers/scsi/ufs/ufshci.h
@@ -190,6 +190,7 @@ enum {
/* UECPA - Host UIC Error Code PHY Adapter Layer 38h */
#define UIC_PHY_ADAPTER_LAYER_ERROR UFS_BIT(31)
+#define UIC_PHY_ADAPTER_LAYER_GENERIC_ERROR UFS_BIT(4)
#define UIC_PHY_ADAPTER_LAYER_ERROR_CODE_MASK 0x1F
#define UIC_PHY_ADAPTER_LAYER_LANE_ERR_MASK 0xF
diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c
index 9cfca014c8ad..382245eb90b6 100644
--- a/drivers/soc/qcom/glink.c
+++ b/drivers/soc/qcom/glink.c
@@ -3948,7 +3948,6 @@ int glink_core_register_transport(struct glink_transport_if *if_ptr,
xprt_ptr->edge, xprt_ptr->name);
if (IS_ERR_OR_NULL(xprt_ptr->tx_task)) {
GLINK_ERR("%s: unable to run thread\n", __func__);
- glink_core_deinit_xprt_qos_cfg(xprt_ptr);
kfree(xprt_ptr);
return -ENOMEM;
}
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index feeed645fc47..6215636b0f46 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -45,6 +45,7 @@
#include <soc/qcom/service-locator.h>
#include <soc/qcom/service-notifier.h>
#include <soc/qcom/socinfo.h>
+#include <soc/qcom/ramdump.h>
#include "wlan_firmware_service_v01.h"
@@ -439,6 +440,7 @@ static struct icnss_priv {
struct wlfw_rf_board_info_s_v01 board_info;
struct wlfw_soc_info_s_v01 soc_info;
struct wlfw_fw_version_info_s_v01 fw_version_info;
+ char fw_build_id[QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1];
u32 pwr_pin_result;
u32 phy_io_pin_result;
u32 rf_pin_result;
@@ -463,6 +465,7 @@ static struct icnss_priv {
struct qpnp_vadc_chip *vadc_dev;
uint64_t vph_pwr;
atomic_t pm_count;
+ struct ramdump_device *msa0_dump_dev;
} *penv;
static void icnss_hw_write_reg(void *base, u32 offset, u32 val)
@@ -1971,12 +1974,16 @@ static int wlfw_cap_send_sync_msg(void)
penv->soc_info = resp.soc_info;
if (resp.fw_version_info_valid)
penv->fw_version_info = resp.fw_version_info;
+ if (resp.fw_build_id_valid)
+ strlcpy(penv->fw_build_id, resp.fw_build_id,
+ QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1);
- icnss_pr_dbg("Capability, chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 0x%x, fw_version: 0x%x, fw_build_timestamp: %s",
+ icnss_pr_dbg("Capability, chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 0x%x, fw_version: 0x%x, fw_build_timestamp: %s, fw_build_id: %s",
penv->chip_info.chip_id, penv->chip_info.chip_family,
penv->board_info.board_id, penv->soc_info.soc_id,
penv->fw_version_info.fw_version,
- penv->fw_version_info.fw_build_timestamp);
+ penv->fw_version_info.fw_build_timestamp,
+ penv->fw_build_id);
return 0;
@@ -2657,8 +2664,6 @@ static int icnss_driver_event_pd_service_down(struct icnss_priv *priv,
out:
ret = icnss_hw_power_off(priv);
- icnss_remove_msa_permissions(priv);
-
kfree(data);
return ret;
@@ -2763,6 +2768,16 @@ static int icnss_qmi_wlfw_clnt_svc_event_notify(struct notifier_block *this,
return ret;
}
+static int icnss_msa0_ramdump(struct icnss_priv *priv)
+{
+ struct ramdump_segment segment;
+
+ memset(&segment, 0, sizeof(segment));
+ segment.v_address = priv->msa_va;
+ segment.size = priv->msa_mem_size;
+ return do_ramdump(priv->msa0_dump_dev, &segment, 1);
+}
+
static struct notifier_block wlfw_clnt_nb = {
.notifier_call = icnss_qmi_wlfw_clnt_svc_event_notify,
};
@@ -2778,9 +2793,19 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
icnss_pr_dbg("Modem-Notify: event %lu\n", code);
+ if (code == SUBSYS_AFTER_SHUTDOWN) {
+ icnss_remove_msa_permissions(priv);
+ icnss_pr_info("Collecting msa0 segment dump\n");
+ icnss_msa0_ramdump(priv);
+ return NOTIFY_OK;
+ }
+
if (code != SUBSYS_BEFORE_SHUTDOWN)
return NOTIFY_OK;
+ if (test_bit(ICNSS_PDR_ENABLED, &priv->state))
+ return NOTIFY_OK;
+
icnss_pr_info("Modem went down, state: %lx\n", priv->state);
event_data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -2936,8 +2961,6 @@ static int icnss_get_service_location_notify(struct notifier_block *nb,
set_bit(ICNSS_PDR_ENABLED, &priv->state);
- icnss_modem_ssr_unregister_notifier(priv);
-
icnss_pr_dbg("PD restart enabled, state: 0x%lx\n", priv->state);
return NOTIFY_OK;
@@ -3000,6 +3023,11 @@ static int icnss_enable_recovery(struct icnss_priv *priv)
goto enable_pdr;
}
+ priv->msa0_dump_dev = create_ramdump_device("wcss_msa0",
+ &priv->pdev->dev);
+ if (!priv->msa0_dump_dev)
+ return -ENOMEM;
+
icnss_modem_ssr_register_notifier(priv);
if (test_bit(SSR_ONLY, &quirks)) {
icnss_pr_dbg("PDR disabled through module parameter\n");
@@ -3929,6 +3957,8 @@ static int icnss_stats_show_capability(struct seq_file *s,
priv->fw_version_info.fw_version);
seq_printf(s, "Firmware Build Timestamp: %s\n",
priv->fw_version_info.fw_build_timestamp);
+ seq_printf(s, "Firmware Build ID: %s\n",
+ priv->fw_build_id);
}
return 0;
@@ -4511,6 +4541,8 @@ static int icnss_remove(struct platform_device *pdev)
icnss_modem_ssr_unregister_notifier(penv);
+ destroy_ramdump_device(penv->msa0_dump_dev);
+
icnss_pdr_unregister_notifier(penv);
qmi_svc_event_notifier_unregister(WLFW_SERVICE_ID_V01,
@@ -4522,6 +4554,8 @@ static int icnss_remove(struct platform_device *pdev)
icnss_hw_power_off(penv);
+ icnss_remove_msa_permissions(penv);
+
dev_set_drvdata(&pdev->dev, NULL);
return 0;
diff --git a/drivers/soc/qcom/memshare/msm_memshare.c b/drivers/soc/qcom/memshare/msm_memshare.c
index 00cc5e12709b..dcca82fc25c6 100644
--- a/drivers/soc/qcom/memshare/msm_memshare.c
+++ b/drivers/soc/qcom/memshare/msm_memshare.c
@@ -39,6 +39,7 @@ static DECLARE_DELAYED_WORK(work_recv_msg, mem_share_svc_recv_msg);
static struct workqueue_struct *mem_share_svc_workqueue;
static uint64_t bootup_request;
static void *memshare_ramdump_dev[MAX_CLIENTS];
+static struct device *memshare_dev[MAX_CLIENTS];
/* Memshare Driver Structure */
struct memshare_driver {
@@ -145,9 +146,14 @@ static int mem_share_configure_ramdump(void)
}
snprintf(client_name, 18, "memshare_%s", clnt);
-
- memshare_ramdump_dev[num_clients] = create_ramdump_device(client_name,
- NULL);
+ if (memshare_dev[num_clients]) {
+ memshare_ramdump_dev[num_clients] =
+ create_ramdump_device(client_name,
+ memshare_dev[num_clients]);
+ } else {
+ pr_err("memshare:%s: invalid memshare device\n", __func__);
+ return -ENODEV;
+ }
if (IS_ERR_OR_NULL(memshare_ramdump_dev[num_clients])) {
pr_err("memshare: %s: Unable to create memshare ramdump device.\n",
__func__);
@@ -957,6 +963,8 @@ static int memshare_child_probe(struct platform_device *pdev)
* memshare clients
*/
+ memshare_dev[num_clients] = &pdev->dev;
+
if (!memblock[num_clients].file_created) {
rc = mem_share_configure_ramdump();
if (rc)
diff --git a/drivers/soc/qcom/msm_smem.c b/drivers/soc/qcom/msm_smem.c
index cd3d387645fd..8f5ad7af8d0d 100644
--- a/drivers/soc/qcom/msm_smem.c
+++ b/drivers/soc/qcom/msm_smem.c
@@ -84,6 +84,7 @@ static int smem_module_inited;
static RAW_NOTIFIER_HEAD(smem_module_init_notifier_list);
static DEFINE_MUTEX(smem_module_init_notifier_lock);
static bool probe_done;
+uint32_t smem_max_items;
/* smem security feature components */
#define SMEM_TOC_IDENTIFIER 0x434f5424 /* "$TOC" */
@@ -139,6 +140,11 @@ struct smem_partition_info {
};
static struct smem_partition_info partitions[NUM_SMEM_SUBSYSTEMS];
+
+#define SMEM_COMM_PART_VERSION 0x000C
+#define SMEM_COMM_HOST 0xFFFE
+static bool use_comm_partition;
+static struct smem_partition_info comm_partition;
/* end smem security feature components */
/* Identifier for the SMEM target info struct. */
@@ -149,6 +155,7 @@ struct smem_targ_info_type {
uint32_t identifier;
uint32_t size;
phys_addr_t phys_base_addr;
+ uint32_t max_items;
};
struct restart_notifier_block {
@@ -312,7 +319,7 @@ static void *__smem_get_entry_nonsecure(unsigned id, unsigned *size,
if (!skip_init_check && !smem_initialized_check())
return ret;
- if (id >= SMEM_NUM_ITEMS)
+ if (id >= smem_max_items)
return ret;
if (use_spinlocks) {
@@ -374,7 +381,7 @@ static void *__smem_get_entry_secure(unsigned id,
if (!skip_init_check && !smem_initialized_check())
return NULL;
- if (id >= SMEM_NUM_ITEMS) {
+ if (id >= smem_max_items) {
SMEM_INFO("%s: invalid id %d\n", __func__, id);
return NULL;
}
@@ -385,12 +392,18 @@ static void *__smem_get_entry_secure(unsigned id,
return NULL;
}
- if (flags & SMEM_ANY_HOST_FLAG || !partitions[to_proc].offset)
- return __smem_get_entry_nonsecure(id, size, skip_init_check,
- use_rspinlock);
-
- partition_num = partitions[to_proc].partition_num;
- hdr = smem_areas[0].virt_addr + partitions[to_proc].offset;
+ if (flags & SMEM_ANY_HOST_FLAG || !partitions[to_proc].offset) {
+ if (use_comm_partition) {
+ partition_num = comm_partition.partition_num;
+ hdr = smem_areas[0].virt_addr + comm_partition.offset;
+ } else {
+ return __smem_get_entry_nonsecure(id, size,
+ skip_init_check, use_rspinlock);
+ }
+ } else {
+ partition_num = partitions[to_proc].partition_num;
+ hdr = smem_areas[0].virt_addr + partitions[to_proc].offset;
+ }
if (unlikely(!spinlocks_initialized)) {
rc = init_smem_remote_spinlock();
if (unlikely(rc)) {
@@ -613,8 +626,19 @@ static void *alloc_item_secure(unsigned id, unsigned size_in, unsigned to_proc,
uint32_t partition_num;
void *ret = NULL;
- hdr = smem_base + partitions[to_proc].offset;
- partition_num = partitions[to_proc].partition_num;
+ if (to_proc == SMEM_COMM_HOST) {
+ hdr = smem_base + comm_partition.offset;
+ partition_num = comm_partition.partition_num;
+ size_cacheline = comm_partition.size_cacheline;
+ } else if (to_proc < NUM_SMEM_SUBSYSTEMS) {
+ hdr = smem_base + partitions[to_proc].offset;
+ partition_num = partitions[to_proc].partition_num;
+ size_cacheline = partitions[to_proc].size_cacheline;
+ } else {
+ SMEM_INFO("%s: invalid to_proc %u for id %u\n", __func__,
+ to_proc, id);
+ return NULL;
+ }
if (hdr->identifier != SMEM_PART_HDR_IDENTIFIER) {
LOG_ERR(
@@ -626,7 +650,6 @@ static void *alloc_item_secure(unsigned id, unsigned size_in, unsigned to_proc,
BUG();
}
- size_cacheline = partitions[to_proc].size_cacheline;
free_space = hdr->offset_free_cached -
hdr->offset_free_uncached;
@@ -718,7 +741,7 @@ void *smem_alloc(unsigned id, unsigned size_in, unsigned to_proc,
if (!smem_initialized_check())
return NULL;
- if (id >= SMEM_NUM_ITEMS) {
+ if (id >= smem_max_items) {
SMEM_INFO("%s: invalid id %u\n", __func__, id);
return NULL;
}
@@ -761,11 +784,16 @@ void *smem_alloc(unsigned id, unsigned size_in, unsigned to_proc,
if (id > SMEM_FIXED_ITEM_LAST) {
SMEM_INFO("%s: allocating %u size %u to_proc %u flags %u\n",
__func__, id, size_in, to_proc, flags);
- if (flags & SMEM_ANY_HOST_FLAG || !partitions[to_proc].offset)
- ret = alloc_item_nonsecure(id, a_size_in);
- else
+ if (flags & SMEM_ANY_HOST_FLAG
+ || !partitions[to_proc].offset) {
+ if (use_comm_partition)
+ ret = alloc_item_secure(id, size_in,
+ SMEM_COMM_HOST, flags);
+ else
+ ret = alloc_item_nonsecure(id, a_size_in);
+ } else {
ret = alloc_item_secure(id, size_in, to_proc, flags);
-
+ }
} else {
SMEM_INFO("%s: attempted to allocate non-dynamic item %u\n",
__func__, id);
@@ -893,14 +921,18 @@ EXPORT_SYMBOL(smem_get_free_space);
unsigned smem_get_version(unsigned idx)
{
int *version_array;
+ struct smem_shared *smem = smem_ram_base;
if (idx > 32) {
pr_err("%s: invalid idx:%d\n", __func__, idx);
return 0;
}
- version_array = __smem_find(SMEM_VERSION_INFO, SMEM_VERSION_INFO_SIZE,
- true);
+ if (use_comm_partition)
+ version_array = smem->version;
+ else
+ version_array = __smem_find(SMEM_VERSION_INFO,
+ SMEM_VERSION_INFO_SIZE, true);
if (version_array == NULL)
return 0;
@@ -948,6 +980,7 @@ bool smem_initialized_check(void)
static int is_inited;
unsigned long flags;
struct smem_shared *smem;
+ unsigned ver;
if (likely(checked)) {
if (unlikely(!is_inited))
@@ -976,8 +1009,12 @@ bool smem_initialized_check(void)
* structures. Without the extra configuration data, the SMEM driver
* cannot be properly initialized.
*/
- if (smem_get_version(MODEM_SBL_VERSION_INDEX) != SMEM_VERSION << 16) {
- pr_err("%s: SBL version not correct\n", __func__);
+ ver = smem->version[MODEM_SBL_VERSION_INDEX];
+ if (ver == SMEM_COMM_PART_VERSION << 16) {
+ use_comm_partition = true;
+ } else if (ver != SMEM_VERSION << 16) {
+ pr_err("%s: SBL version not correct 0x%x\n",
+ __func__, smem->version[7]);
goto failed;
}
@@ -1122,6 +1159,7 @@ static void smem_init_security_partition(struct smem_toc_entry *entry,
{
uint16_t remote_host;
struct smem_partition_header *hdr;
+ bool is_comm_partition = false;
if (!entry->offset) {
SMEM_INFO("Skipping smem partition %d - bad offset\n", num);
@@ -1136,31 +1174,38 @@ static void smem_init_security_partition(struct smem_toc_entry *entry,
return;
}
- if (entry->host0 == SMEM_APPS)
- remote_host = entry->host1;
- else
- remote_host = entry->host0;
+ if (entry->host0 == SMEM_COMM_HOST && entry->host1 == SMEM_COMM_HOST)
+ is_comm_partition = true;
- if (remote_host >= NUM_SMEM_SUBSYSTEMS) {
- SMEM_INFO("Skipping smem partition %d - bad remote:%d\n", num,
- remote_host);
- return;
- }
- if (partitions[remote_host].offset) {
- SMEM_INFO("Skipping smem partition %d - duplicate of %d\n", num,
- partitions[remote_host].partition_num);
- return;
- }
+ if (!is_comm_partition) {
+ if (entry->host0 == SMEM_APPS)
+ remote_host = entry->host1;
+ else
+ remote_host = entry->host0;
- hdr = smem_areas[0].virt_addr + entry->offset;
+ if (remote_host >= NUM_SMEM_SUBSYSTEMS) {
+ SMEM_INFO(
+ "Skipping smem partition %d - bad remote:%d\n",
+ num, remote_host);
+ return;
+ }
+ if (partitions[remote_host].offset) {
+ SMEM_INFO(
+ "Skipping smem partition %d - duplicate of %d\n",
+ num, partitions[remote_host].partition_num);
+ return;
+ }
- if (entry->host0 != SMEM_APPS && entry->host1 != SMEM_APPS) {
- SMEM_INFO(
- "Non-APSS Partition %d offset:%x host0:%d host1:%d\n",
- num, entry->offset, entry->host0, entry->host1);
- return;
+ if (entry->host0 != SMEM_APPS && entry->host1 != SMEM_APPS) {
+ SMEM_INFO(
+ "Non-APSS Partition %d offset:%x host0:%d host1:%d\n",
+ num, entry->offset, entry->host0, entry->host1);
+ return;
+ }
}
+ hdr = smem_areas[0].virt_addr + entry->offset;
+
if (hdr->identifier != SMEM_PART_HDR_IDENTIFIER) {
LOG_ERR("Smem partition %d hdr magic is bad\n", num);
BUG();
@@ -1177,6 +1222,14 @@ static void smem_init_security_partition(struct smem_toc_entry *entry,
LOG_ERR("Smem partition %d cached heap exceeds size\n", num);
BUG();
}
+ if (hdr->host0 == SMEM_COMM_HOST && hdr->host1 == SMEM_COMM_HOST) {
+ comm_partition.partition_num = num;
+ comm_partition.offset = entry->offset;
+ comm_partition.size_cacheline = entry->size_cacheline;
+ SMEM_INFO("Common Partition %d offset:%x\n", num,
+ entry->offset);
+ return;
+ }
if (hdr->host0 != SMEM_APPS && hdr->host1 != SMEM_APPS) {
LOG_ERR("Smem partition %d hosts don't match TOC\n", num);
BUG();
@@ -1253,6 +1306,8 @@ static int smem_init_target_info(phys_addr_t info_addr, resource_size_t size)
}
smem_ram_phys = smem_targ_info->phys_base_addr;
smem_ram_size = smem_targ_info->size;
+ if (smem_targ_info->max_items)
+ smem_max_items = smem_targ_info->max_items;
iounmap(smem_targ_info_addr);
return 0;
}
@@ -1488,7 +1543,7 @@ int __init msm_smem_init(void)
return 0;
registered = true;
-
+ smem_max_items = SMEM_NUM_ITEMS;
smem_ipc_log_ctx = ipc_log_context_create(NUM_LOG_PAGES, "smem", 0);
if (!smem_ipc_log_ctx) {
pr_err("%s: unable to create logging context\n", __func__);
diff --git a/drivers/soc/qcom/secure_buffer.c b/drivers/soc/qcom/secure_buffer.c
index afe6b2309e27..95d50fe01ee1 100644
--- a/drivers/soc/qcom/secure_buffer.c
+++ b/drivers/soc/qcom/secure_buffer.c
@@ -260,7 +260,7 @@ int hyp_assign_table(struct sg_table *table,
int *dest_vmids, int *dest_perms,
int dest_nelems)
{
- int ret;
+ int ret = 0;
struct scm_desc desc = {0};
u32 *source_vm_copy;
size_t source_vm_copy_size;
diff --git a/drivers/soc/qcom/smem_debug.c b/drivers/soc/qcom/smem_debug.c
index ace89afb614c..766a1781e6b9 100644
--- a/drivers/soc/qcom/smem_debug.c
+++ b/drivers/soc/qcom/smem_debug.c
@@ -1,7 +1,7 @@
/* arch/arm/mach-msm/smem_debug.c
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2013,2016 The Linux Foundation. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -53,7 +53,7 @@ static void debug_read_mem(struct seq_file *s)
heap_info->free_offset,
heap_info->heap_remaining);
- for (n = 0; n < SMEM_NUM_ITEMS; n++) {
+ for (n = 0; n < smem_max_items; n++) {
if (toc[n].allocated == 0)
continue;
seq_printf(s, "%04d: offset %08x size %08x\n",
@@ -67,9 +67,8 @@ static void debug_read_smem_version(struct seq_file *s)
for (n = 0; n < 32; n++) {
version = smem_get_version(n);
- seq_printf(s, "entry %d: smem = %d proc_comm = %d\n", n,
- version >> 16,
- version & 0xffff);
+ seq_printf(s, "entry %d:%x smem = %d proc_comm = %d\n",
+ n, version, version >> 16, version & 0xffff);
}
}
diff --git a/drivers/soc/qcom/smem_private.h b/drivers/soc/qcom/smem_private.h
index 7aeca5eed8d2..ddbc29e30dfb 100644
--- a/drivers/soc/qcom/smem_private.h
+++ b/drivers/soc/qcom/smem_private.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013,2016 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
@@ -18,6 +18,7 @@
#define SMD_HEAP_SIZE 512
+extern uint32_t smem_max_items;
struct smem_heap_info {
unsigned initialized;
diff --git a/drivers/soc/qcom/sysmon.c b/drivers/soc/qcom/sysmon.c
index 8a12341a6f91..f8d0f10b1173 100644
--- a/drivers/soc/qcom/sysmon.c
+++ b/drivers/soc/qcom/sysmon.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014,2016 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
@@ -206,7 +206,7 @@ int sysmon_send_shutdown_no_qmi(struct subsys_desc *dest_desc)
return -ENODEV;
mutex_lock(&ss->lock);
- ret = sysmon_send_msg(ss, tx_buf, ARRAY_SIZE(tx_buf));
+ ret = sysmon_send_msg(ss, tx_buf, strlen(tx_buf));
if (ret) {
pr_err("Message sending failed %d\n", ret);
goto out;
@@ -257,7 +257,7 @@ int sysmon_get_reason_no_qmi(struct subsys_desc *dest_desc,
return -ENODEV;
mutex_lock(&ss->lock);
- ret = sysmon_send_msg(ss, tx_buf, ARRAY_SIZE(tx_buf));
+ ret = sysmon_send_msg(ss, tx_buf, strlen(tx_buf));
if (ret) {
pr_err("Message sending failed %d\n", ret);
goto out;
diff --git a/drivers/soc/qcom/wlan_firmware_service_v01.c b/drivers/soc/qcom/wlan_firmware_service_v01.c
index f5f7ae8c9901..3e00d6c9d153 100644
--- a/drivers/soc/qcom/wlan_firmware_service_v01.c
+++ b/drivers/soc/qcom/wlan_firmware_service_v01.c
@@ -766,6 +766,24 @@ struct elem_info wlfw_cap_resp_msg_v01_ei[] = {
.ei_array = wlfw_fw_version_info_s_v01_ei,
},
{
+ .data_type = QMI_OPT_FLAG,
+ .elem_len = 1,
+ .elem_size = sizeof(uint8_t),
+ .is_array = NO_ARRAY,
+ .tlv_type = 0x14,
+ .offset = offsetof(struct wlfw_cap_resp_msg_v01,
+ fw_build_id_valid),
+ },
+ {
+ .data_type = QMI_STRING,
+ .elem_len = QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1,
+ .elem_size = sizeof(char),
+ .is_array = NO_ARRAY,
+ .tlv_type = 0x14,
+ .offset = offsetof(struct wlfw_cap_resp_msg_v01,
+ fw_build_id),
+ },
+ {
.data_type = QMI_EOTI,
.is_array = NO_ARRAY,
.is_array = QMI_COMMON_TLV_TYPE,
@@ -1588,3 +1606,47 @@ struct elem_info wlfw_vbatt_resp_msg_v01_ei[] = {
.is_array = QMI_COMMON_TLV_TYPE,
},
};
+
+struct elem_info wlfw_mac_addr_req_msg_v01_ei[] = {
+ {
+ .data_type = QMI_OPT_FLAG,
+ .elem_len = 1,
+ .elem_size = sizeof(uint8_t),
+ .is_array = NO_ARRAY,
+ .tlv_type = 0x10,
+ .offset = offsetof(struct wlfw_mac_addr_req_msg_v01,
+ mac_addr_valid),
+ },
+ {
+ .data_type = QMI_UNSIGNED_1_BYTE,
+ .elem_len = QMI_WLFW_MAC_ADDR_SIZE_V01,
+ .elem_size = sizeof(uint8_t),
+ .is_array = STATIC_ARRAY,
+ .tlv_type = 0x10,
+ .offset = offsetof(struct wlfw_mac_addr_req_msg_v01,
+ mac_addr),
+ },
+ {
+ .data_type = QMI_EOTI,
+ .is_array = NO_ARRAY,
+ .is_array = QMI_COMMON_TLV_TYPE,
+ },
+};
+
+struct elem_info wlfw_mac_addr_resp_msg_v01_ei[] = {
+ {
+ .data_type = QMI_STRUCT,
+ .elem_len = 1,
+ .elem_size = sizeof(struct qmi_response_type_v01),
+ .is_array = NO_ARRAY,
+ .tlv_type = 0x02,
+ .offset = offsetof(struct wlfw_mac_addr_resp_msg_v01,
+ resp),
+ .ei_array = get_qmi_response_type_v01_ei(),
+ },
+ {
+ .data_type = QMI_EOTI,
+ .is_array = NO_ARRAY,
+ .is_array = QMI_COMMON_TLV_TYPE,
+ },
+};
diff --git a/drivers/soc/qcom/wlan_firmware_service_v01.h b/drivers/soc/qcom/wlan_firmware_service_v01.h
index 29bdfb23480a..47b315fce94c 100644
--- a/drivers/soc/qcom/wlan_firmware_service_v01.h
+++ b/drivers/soc/qcom/wlan_firmware_service_v01.h
@@ -24,6 +24,7 @@
#define QMI_WLFW_CAL_DOWNLOAD_RESP_V01 0x0027
#define QMI_WLFW_INI_RESP_V01 0x002F
#define QMI_WLFW_CAL_REPORT_RESP_V01 0x0026
+#define QMI_WLFW_MAC_ADDR_RESP_V01 0x0033
#define QMI_WLFW_INITIATE_CAL_DOWNLOAD_IND_V01 0x0028
#define QMI_WLFW_MSA_READY_IND_V01 0x002B
#define QMI_WLFW_ATHDIAG_WRITE_RESP_V01 0x0031
@@ -43,6 +44,7 @@
#define QMI_WLFW_CAP_RESP_V01 0x0024
#define QMI_WLFW_ATHDIAG_READ_RESP_V01 0x0030
#define QMI_WLFW_VBATT_REQ_V01 0x0032
+#define QMI_WLFW_MAC_ADDR_REQ_V01 0x0033
#define QMI_WLFW_VBATT_RESP_V01 0x0032
#define QMI_WLFW_MSA_INFO_REQ_V01 0x002D
#define QMI_WLFW_CAL_DOWNLOAD_REQ_V01 0x0027
@@ -57,6 +59,8 @@
#define QMI_WLFW_MAX_TIMESTAMP_LEN_V01 32
#define QMI_WLFW_MAX_STR_LEN_V01 16
#define QMI_WLFW_MAX_NUM_SHADOW_REG_V01 24
+#define QMI_WLFW_MAC_ADDR_SIZE_V01 6
+#define QMI_WLFW_MAX_BUILD_ID_LEN_V01 128
#define QMI_WLFW_MAX_NUM_SVC_V01 24
enum wlfw_driver_mode_enum_v01 {
@@ -99,6 +103,7 @@ enum wlfw_pipedir_enum_v01 {
#define QMI_WLFW_ALREADY_REGISTERED_V01 ((uint64_t)0x01ULL)
#define QMI_WLFW_FW_READY_V01 ((uint64_t)0x02ULL)
+#define QMI_WLFW_MSA_READY_V01 ((uint64_t)0x04ULL)
struct wlfw_ce_tgt_pipe_cfg_s_v01 {
uint32_t pipe_num;
@@ -243,8 +248,10 @@ struct wlfw_cap_resp_msg_v01 {
struct wlfw_soc_info_s_v01 soc_info;
uint8_t fw_version_info_valid;
struct wlfw_fw_version_info_s_v01 fw_version_info;
+ uint8_t fw_build_id_valid;
+ char fw_build_id[QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1];
};
-#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 72
+#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 203
extern struct elem_info wlfw_cap_resp_msg_v01_ei[];
struct wlfw_bdf_download_req_msg_v01 {
@@ -428,4 +435,17 @@ struct wlfw_vbatt_resp_msg_v01 {
#define WLFW_VBATT_RESP_MSG_V01_MAX_MSG_LEN 7
extern struct elem_info wlfw_vbatt_resp_msg_v01_ei[];
+struct wlfw_mac_addr_req_msg_v01 {
+ uint8_t mac_addr_valid;
+ uint8_t mac_addr[QMI_WLFW_MAC_ADDR_SIZE_V01];
+};
+#define WLFW_MAC_ADDR_REQ_MSG_V01_MAX_MSG_LEN 9
+extern struct elem_info wlfw_mac_addr_req_msg_v01_ei[];
+
+struct wlfw_mac_addr_resp_msg_v01 {
+ struct qmi_response_type_v01 resp;
+};
+#define WLFW_MAC_ADDR_RESP_MSG_V01_MAX_MSG_LEN 7
+extern struct elem_info wlfw_mac_addr_resp_msg_v01_ei[];
+
#endif
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index c0b936d802ef..0ae654a921f8 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -24,6 +24,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spmi.h>
+#include <linux/syscore_ops.h>
/* PMIC Arbiter configuration registers */
#define PMIC_ARB_VERSION 0x0000
@@ -159,6 +160,7 @@ struct spmi_pmic_arb {
u16 last_apid;
struct apid_data apid_data[PMIC_ARB_MAX_PERIPHS];
};
+static struct spmi_pmic_arb *the_pa;
/**
* pmic_arb_ver: version dependent functionality.
@@ -525,7 +527,7 @@ static void cleanup_irq(struct spmi_pmic_arb *pa, u16 apid, int id)
irq_mask, ppid);
}
-static void periph_interrupt(struct spmi_pmic_arb *pa, u16 apid)
+static void periph_interrupt(struct spmi_pmic_arb *pa, u16 apid, bool show)
{
unsigned int irq;
u32 status;
@@ -542,22 +544,32 @@ static void periph_interrupt(struct spmi_pmic_arb *pa, u16 apid)
cleanup_irq(pa, apid, id);
continue;
}
- generic_handle_irq(irq);
+ if (show) {
+ struct irq_desc *desc;
+ const char *name = "null";
+
+ desc = irq_to_desc(irq);
+ if (desc == NULL)
+ name = "stray irq";
+ else if (desc->action && desc->action->name)
+ name = desc->action->name;
+
+ pr_warn("spmi_show_resume_irq: %d triggered [0x%01x, 0x%02x, 0x%01x] %s\n",
+ irq, sid, per, id, name);
+ } else {
+ generic_handle_irq(irq);
+ }
}
}
-static void pmic_arb_chained_irq(struct irq_desc *desc)
+static void __pmic_arb_chained_irq(struct spmi_pmic_arb *pa, bool show)
{
- struct spmi_pmic_arb *pa = irq_desc_get_handler_data(desc);
- struct irq_chip *chip = irq_desc_get_chip(desc);
void __iomem *intr = pa->intr;
int first = pa->min_apid >> 5;
int last = pa->max_apid >> 5;
u32 status, enable;
int i, id, apid;
- chained_irq_enter(chip, desc);
-
for (i = first; i <= last; ++i) {
status = readl_relaxed(intr +
pa->ver_ops->owner_acc_status(pa->ee, i));
@@ -568,10 +580,18 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
enable = readl_relaxed(intr +
pa->ver_ops->acc_enable(apid));
if (enable & SPMI_PIC_ACC_ENABLE_BIT)
- periph_interrupt(pa, apid);
+ periph_interrupt(pa, apid, show);
}
}
+}
+
+static void pmic_arb_chained_irq(struct irq_desc *desc)
+{
+ struct spmi_pmic_arb *pa = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ chained_irq_enter(chip, desc);
+ __pmic_arb_chained_irq(pa, false);
chained_irq_exit(chip, desc);
}
@@ -988,6 +1008,16 @@ static const struct irq_domain_ops pmic_arb_irq_domain_ops = {
.xlate = qpnpint_irq_domain_dt_translate,
};
+static void spmi_pmic_arb_resume(void)
+{
+ if (spmi_show_resume_irq())
+ __pmic_arb_chained_irq(the_pa, true);
+}
+
+static struct syscore_ops spmi_pmic_arb_syscore_ops = {
+ .resume = spmi_pmic_arb_resume,
+};
+
static int spmi_pmic_arb_probe(struct platform_device *pdev)
{
struct spmi_pmic_arb *pa;
@@ -1153,6 +1183,8 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
if (err)
goto err_domain_remove;
+ the_pa = pa;
+ register_syscore_ops(&spmi_pmic_arb_syscore_ops);
return 0;
err_domain_remove:
@@ -1167,8 +1199,11 @@ static int spmi_pmic_arb_remove(struct platform_device *pdev)
{
struct spmi_controller *ctrl = platform_get_drvdata(pdev);
struct spmi_pmic_arb *pa = spmi_controller_get_drvdata(ctrl);
+
spmi_controller_remove(ctrl);
irq_set_chained_handler_and_data(pa->irq, NULL, NULL);
+ unregister_syscore_ops(&spmi_pmic_arb_syscore_ops);
+ the_pa = NULL;
irq_domain_remove(pa->domain);
spmi_controller_put(ctrl);
return 0;
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index ced2f23addd4..002cafb08f37 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -60,6 +60,7 @@
#define MSM_LIMITS_NODE_DCVS 0x44435653
#define MSM_LIMITS_SUB_FN_GENERAL 0x47454E00
#define MSM_LIMITS_SUB_FN_CRNT 0x43524E54
+#define MSM_LIMITS_SUB_FN_REL 0x52454C00
#define MSM_LIMITS_DOMAIN_MAX 0x444D4158
#define MSM_LIMITS_DOMAIN_MIN 0x444D494E
#define MSM_LIMITS_CLUSTER_0 0x6370302D
@@ -1674,7 +1675,20 @@ static int msm_thermal_lmh_dcvs_init(struct platform_device *pdev)
*/
devm_clk_put(&pdev->dev, osm_clk);
- /* Enable the CRNT algorithm. Again, we dont care if this fails */
+ /* Enable the CRNT and Reliability algorithm. Again, we dont
+ * care if this fails
+ */
+ ret = msm_lmh_dcvs_write(MSM_LIMITS_CLUSTER_0,
+ MSM_LIMITS_SUB_FN_REL,
+ MSM_LIMITS_ALGO_MODE_ENABLE, 1);
+ if (ret)
+ pr_err("Unable to enable REL algo for cluster0\n");
+ ret = msm_lmh_dcvs_write(MSM_LIMITS_CLUSTER_1,
+ MSM_LIMITS_SUB_FN_REL,
+ MSM_LIMITS_ALGO_MODE_ENABLE, 1);
+ if (ret)
+ pr_err("Unable to enable REL algo for cluster1\n");
+
ret = msm_lmh_dcvs_write(MSM_LIMITS_CLUSTER_0,
MSM_LIMITS_SUB_FN_CRNT,
MSM_LIMITS_ALGO_MODE_ENABLE, 1);
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index dadd1e8dfe09..26a305f43ff6 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1441,6 +1441,9 @@ int usb_suspend(struct device *dev, pm_message_t msg)
{
struct usb_device *udev = to_usb_device(dev);
+ if (udev->bus->skip_resume && udev->state == USB_STATE_SUSPENDED)
+ return 0;
+
unbind_no_pm_drivers_interfaces(udev);
/* From now on we are sure all drivers support suspend/resume
@@ -1470,6 +1473,15 @@ int usb_resume(struct device *dev, pm_message_t msg)
struct usb_device *udev = to_usb_device(dev);
int status;
+ /*
+ * Some buses would like to keep their devices in suspend
+ * state after system resume. Their resume happen when
+ * a remote wakeup is detected or interface driver start
+ * I/O.
+ */
+ if (udev->bus->skip_resume)
+ return 0;
+
/* For all calls, take the device back to full power and
* tell the PM core in case it was autosuspended previously.
* Unbind the interfaces that will need rebinding later,
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 269c1ee2da44..5839111ab4e0 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -48,6 +48,11 @@ static void hub_event(struct work_struct *work);
/* synchronize hub-port add/remove and peering operations */
DEFINE_MUTEX(usb_port_peer_mutex);
+static bool skip_extended_resume_delay = 1;
+module_param(skip_extended_resume_delay, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(skip_extended_resume_delay,
+ "removes extra delay added to finish bus resume");
+
/* cycle leds on hubs that aren't blinking for attention */
static bool blinkenlights = 0;
module_param(blinkenlights, bool, S_IRUGO);
@@ -3434,7 +3439,9 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
/* drive resume for USB_RESUME_TIMEOUT msec */
dev_dbg(&udev->dev, "usb %sresume\n",
(PMSG_IS_AUTO(msg) ? "auto-" : ""));
- msleep(USB_RESUME_TIMEOUT);
+ if (!skip_extended_resume_delay)
+ usleep_range(USB_RESUME_TIMEOUT * 1000,
+ (USB_RESUME_TIMEOUT + 1) * 1000);
/* Virtual root hubs can trigger on GET_PORT_STATUS to
* stop resume signaling. Then finish the resume
@@ -3443,7 +3450,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
status = hub_port_status(hub, port1, &portstatus, &portchange);
/* TRSMRCY = 10 msec */
- msleep(10);
+ usleep_range(10000, 10500);
}
SuspendCleared:
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index 5db4fe9e3cdf..be29dc4bef89 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -1528,7 +1528,14 @@ static int android_setup(struct usb_gadget *gadget,
static void android_disconnect(struct usb_gadget *gadget)
{
struct usb_composite_dev *cdev = get_gadget_data(gadget);
- struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
+ struct gadget_info *gi;
+
+ if (!cdev) {
+ pr_err("%s: gadget is not connected\n", __func__);
+ return;
+ }
+
+ gi = container_of(cdev, struct gadget_info, cdev);
/* accessory HID support can be active while the
accessory function is not actually enabled,
diff --git a/drivers/usb/gadget/function/f_mtp.c b/drivers/usb/gadget/function/f_mtp.c
index 5e50fe245a59..33f7304eac84 100644
--- a/drivers/usb/gadget/function/f_mtp.c
+++ b/drivers/usb/gadget/function/f_mtp.c
@@ -43,6 +43,7 @@
#include "configfs.h"
#define MTP_RX_BUFFER_INIT_SIZE 1048576
+#define MTP_TX_BUFFER_INIT_SIZE 1048576
#define MTP_BULK_BUFFER_SIZE 16384
#define INTR_BUFFER_SIZE 28
#define MAX_INST_NAME_LEN 40
@@ -81,7 +82,7 @@
unsigned int mtp_rx_req_len = MTP_RX_BUFFER_INIT_SIZE;
module_param(mtp_rx_req_len, uint, S_IRUGO | S_IWUSR);
-unsigned int mtp_tx_req_len = MTP_BULK_BUFFER_SIZE;
+unsigned int mtp_tx_req_len = MTP_TX_BUFFER_INIT_SIZE;
module_param(mtp_tx_req_len, uint, S_IRUGO | S_IWUSR);
unsigned int mtp_tx_reqs = MTP_TX_REQ_MAX;
@@ -551,9 +552,6 @@ static int mtp_create_bulk_endpoints(struct mtp_dev *dev,
dev->ep_intr = ep;
retry_tx_alloc:
- if (mtp_tx_req_len > MTP_BULK_BUFFER_SIZE)
- mtp_tx_reqs = 4;
-
/* now allocate requests for our endpoints */
for (i = 0; i < mtp_tx_reqs; i++) {
req = mtp_request_new(dev->ep_in, mtp_tx_req_len);
@@ -753,8 +751,8 @@ static ssize_t mtp_write(struct file *fp, const char __user *buf,
break;
}
- if (count > MTP_BULK_BUFFER_SIZE)
- xfer = MTP_BULK_BUFFER_SIZE;
+ if (count > mtp_tx_req_len)
+ xfer = mtp_tx_req_len;
else
xfer = count;
if (xfer && copy_from_user(req->buf, buf, xfer)) {
@@ -850,8 +848,8 @@ static void send_file_work(struct work_struct *data)
break;
}
- if (count > MTP_BULK_BUFFER_SIZE)
- xfer = MTP_BULK_BUFFER_SIZE;
+ if (count > mtp_tx_req_len)
+ xfer = mtp_tx_req_len;
else
xfer = count;
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 0f51d078416e..a7b055bc279a 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -1165,7 +1165,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
xhci_set_link_state(xhci, port_array, wIndex,
XDEV_RESUME);
spin_unlock_irqrestore(&xhci->lock, flags);
- msleep(20);
+ usleep_range(21000, 21500);
spin_lock_irqsave(&xhci->lock, flags);
xhci_set_link_state(xhci, port_array, wIndex,
XDEV_U0);
@@ -1409,7 +1409,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
if (need_usb2_u3_exit) {
spin_unlock_irqrestore(&xhci->lock, flags);
- msleep(20);
+ usleep_range(21000, 21500);
spin_lock_irqsave(&xhci->lock, flags);
}
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 084dbbc81a6d..fcb9b4b822aa 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -167,6 +167,8 @@ static int xhci_plat_probe(struct platform_device *pdev)
if (!hcd)
return -ENOMEM;
+ hcd_to_bus(hcd)->skip_resume = true;
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hcd->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(hcd->regs)) {
@@ -221,6 +223,8 @@ static int xhci_plat_probe(struct platform_device *pdev)
goto disable_clk;
}
+ hcd_to_bus(xhci->shared_hcd)->skip_resume = true;
+
if ((node && of_property_read_bool(node, "usb3-lpm-capable")) ||
(pdata && pdata->usb3_lpm_capable))
xhci->quirks |= XHCI_LPM_SUPPORT;
@@ -332,7 +336,7 @@ static int xhci_plat_runtime_suspend(struct device *dev)
dev_dbg(dev, "xhci-plat runtime suspend\n");
- return xhci_suspend(xhci, true);
+ return 0;
}
static int xhci_plat_runtime_resume(struct device *dev)
@@ -346,7 +350,7 @@ static int xhci_plat_runtime_resume(struct device *dev)
dev_dbg(dev, "xhci-plat runtime resume\n");
- ret = xhci_resume(xhci, false);
+ ret = 0;
pm_runtime_mark_last_busy(dev);
return ret;
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index b4d7c7d8bddf..517110e76157 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -1039,23 +1039,23 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg)
return;
}
- if (handler && handler->svdm_received)
+ /* if this interrupts a previous exchange, abort queued response */
+ if (cmd_type == SVDM_CMD_TYPE_INITIATOR && pd->vdm_tx) {
+ usbpd_dbg(&pd->dev, "Discarding previously queued SVDM tx (SVID:0x%04x)\n",
+ VDM_HDR_SVID(pd->vdm_tx->data[0]));
+
+ kfree(pd->vdm_tx);
+ pd->vdm_tx = NULL;
+ }
+
+ if (handler && handler->svdm_received) {
handler->svdm_received(handler, cmd, cmd_type, vdos, num_vdos);
+ return;
+ }
+ /* Standard Discovery or unhandled messages go here */
switch (cmd_type) {
case SVDM_CMD_TYPE_INITIATOR:
- /*
- * if this interrupts a previous exchange, abort the previous
- * outgoing response
- */
- if (pd->vdm_tx) {
- usbpd_dbg(&pd->dev, "Discarding previously queued SVDM tx (SVID:0x%04x)\n",
- VDM_HDR_SVID(pd->vdm_tx->data[0]));
-
- kfree(pd->vdm_tx);
- pd->vdm_tx = NULL;
- }
-
if (svid == USBPD_SID && cmd == USBPD_SVDM_DISCOVER_IDENTITY) {
u32 tx_vdos[3] = {
ID_HDR_USB_HOST | ID_HDR_USB_DEVICE |
@@ -1074,13 +1074,14 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg)
break;
case SVDM_CMD_TYPE_RESP_ACK:
+ if (svid != USBPD_SID) {
+ usbpd_err(&pd->dev, "unhandled ACK for SVID:0x%x\n",
+ svid);
+ break;
+ }
+
switch (cmd) {
case USBPD_SVDM_DISCOVER_IDENTITY:
- if (svid != USBPD_SID) {
- usbpd_err(&pd->dev, "invalid VID:0x%x\n", svid);
- break;
- }
-
kfree(pd->vdm_tx_retry);
pd->vdm_tx_retry = NULL;
@@ -1091,11 +1092,6 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg)
break;
case USBPD_SVDM_DISCOVER_SVIDS:
- if (svid != USBPD_SID) {
- usbpd_err(&pd->dev, "invalid VID:0x%x\n", svid);
- break;
- }
-
pd->vdm_state = DISCOVERED_SVIDS;
kfree(pd->vdm_tx_retry);
@@ -1181,33 +1177,15 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg)
break;
- case USBPD_SVDM_DISCOVER_MODES:
- usbpd_info(&pd->dev, "SVID:0x%04x VDM Modes discovered\n",
- svid);
- pd->vdm_state = DISCOVERED_MODES;
- break;
-
- case USBPD_SVDM_ENTER_MODE:
- usbpd_info(&pd->dev, "SVID:0x%04x VDM Mode entered\n",
- svid);
- pd->vdm_state = MODE_ENTERED;
- kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
- break;
-
- case USBPD_SVDM_EXIT_MODE:
- usbpd_info(&pd->dev, "SVID:0x%04x VDM Mode exited\n",
- svid);
- pd->vdm_state = MODE_EXITED;
- kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
- break;
-
default:
+ usbpd_dbg(&pd->dev, "unhandled ACK for command:0x%x\n",
+ cmd);
break;
}
break;
case SVDM_CMD_TYPE_RESP_NAK:
- usbpd_info(&pd->dev, "VDM NAK received for SVID:0x%04x command:%d\n",
+ usbpd_info(&pd->dev, "VDM NAK received for SVID:0x%04x command:0x%x\n",
svid, cmd);
break;
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index 75e42ca8cd88..b7561e49955b 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -45,6 +45,11 @@
#define VDDA_UA_ON_LOAD 100000 /* uA units */
#define VDDA_UA_OFF_LOAD 100 /* uA units */
+struct mdss_dp_attention_node {
+ u32 vdo;
+ struct list_head list;
+};
+
#define DEFAULT_VIDEO_RESOLUTION HDMI_VFRMT_640x480p60_4_3
static u32 supported_modes[] = {
HDMI_VFRMT_640x480p60_4_3,
@@ -60,6 +65,7 @@ static u32 supported_modes[] = {
static int mdss_dp_off_irq(struct mdss_dp_drv_pdata *dp_drv);
static void mdss_dp_mainlink_push_idle(struct mdss_panel_data *pdata);
static inline void mdss_dp_link_retraining(struct mdss_dp_drv_pdata *dp);
+static void mdss_dp_handle_attention(struct mdss_dp_drv_pdata *dp_drv);
static void mdss_dp_put_dt_clk_data(struct device *dev,
struct dss_module_power *module_power)
@@ -1133,7 +1139,7 @@ static void mdss_dp_configure_source_params(struct mdss_dp_drv_pdata *dp,
mdss_dp_fill_link_cfg(dp);
mdss_dp_mainlink_ctrl(&dp->ctrl_io, true);
mdss_dp_config_ctrl(dp);
- mdss_dp_sw_mvid_nvid(&dp->ctrl_io);
+ mdss_dp_sw_config_msa(&dp->ctrl_io, dp->link_rate, &dp->dp_cc_io);
mdss_dp_timing_cfg(&dp->ctrl_io, &dp->panel_data.panel_info);
}
@@ -1290,7 +1296,6 @@ link_training:
dp_drv->cont_splash = 0;
dp_drv->power_on = true;
- mdss_dp_ack_state(dp_drv, true);
pr_debug("End-\n");
exit:
@@ -1559,6 +1564,7 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata)
goto edid_error;
}
+ mdss_dp_update_cable_status(dp_drv, true);
mdss_dp_notify_clients(dp_drv, true);
dp_drv->dp_initialized = true;
@@ -1883,8 +1889,13 @@ static void mdss_dp_update_hdcp_info(struct mdss_dp_drv_pdata *dp)
}
/* update internal data about hdcp */
- dp->hdcp.data = fd;
- dp->hdcp.ops = ops;
+ if (dp->hdcp.hdcp2_present || dp->hdcp.hdcp1_present) {
+ dp->hdcp.data = fd;
+ dp->hdcp.ops = ops;
+ } else {
+ dp->hdcp.data = NULL;
+ dp->hdcp.ops = NULL;
+ }
}
static inline bool dp_is_hdcp_enabled(struct mdss_dp_drv_pdata *dp_drv)
@@ -1920,6 +1931,8 @@ static int mdss_dp_event_handler(struct mdss_panel_data *pdata,
if (dp->hdcp.ops && dp->hdcp.ops->authenticate)
rc = dp->hdcp.ops->authenticate(dp->hdcp.data);
+
+ mdss_dp_ack_state(dp, true);
break;
case MDSS_EVENT_PANEL_OFF:
rc = mdss_dp_off(pdata);
@@ -2041,6 +2054,12 @@ static int mdss_retrieve_dp_ctrl_resources(struct platform_device *pdev,
return rc;
}
+ if (msm_dss_ioremap_byname(pdev, &dp_drv->dp_cc_io, "dp_mmss_cc")) {
+ pr_err("%d unable to remap dp MMSS_CC resources\n",
+ __LINE__);
+ return rc;
+ }
+
if (msm_dss_ioremap_byname(pdev, &dp_drv->qfprom_io,
"qfprom_physical"))
pr_warn("unable to remap dp qfprom resources\n");
@@ -2049,7 +2068,7 @@ static int mdss_retrieve_dp_ctrl_resources(struct platform_device *pdev,
"hdcp_physical"))
pr_warn("unable to remap dp hdcp resources\n");
- pr_debug("DP Driver base=%p size=%x\n",
+ pr_debug("DP Driver base=%pK size=%x\n",
dp_drv->base, dp_drv->base_size);
mdss_debug_register_base("dp",
@@ -2117,6 +2136,9 @@ static void mdss_dp_event_work(struct work_struct *work)
case EV_IDLE_PATTERNS_SENT:
mdss_dp_idle_patterns_sent(dp);
break;
+ case EV_USBPD_ATTENTION:
+ mdss_dp_handle_attention(dp);
+ break;
case EV_USBPD_DISCOVER_MODES:
usbpd_send_svdm(dp->pd, USB_C_DP_SID, USBPD_SVDM_DISCOVER_MODES,
SVDM_CMD_TYPE_INITIATOR, 0x0, 0x0, 0x0);
@@ -2225,6 +2247,7 @@ static int mdss_dp_event_setup(struct mdss_dp_drv_pdata *dp)
INIT_WORK(&dp->work, mdss_dp_event_work);
INIT_DELAYED_WORK(&dp->hdcp_cb_work, mdss_dp_hdcp_cb_work);
+ INIT_LIST_HEAD(&dp->attention_head);
return 0;
}
@@ -2508,6 +2531,7 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd,
const u32 *vdos, int num_vdos)
{
struct mdss_dp_drv_pdata *dp_drv;
+ struct mdss_dp_attention_node *node;
dp_drv = container_of(hdlr, struct mdss_dp_drv_pdata, svid_handler);
if (!dp_drv->pd) {
@@ -2535,45 +2559,14 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd,
dp_send_events(dp_drv, EV_USBPD_DP_STATUS);
break;
case USBPD_SVDM_ATTENTION:
- dp_drv->alt_mode.dp_status.response = *vdos;
- mdss_dp_usbpd_ext_dp_status(&dp_drv->alt_mode.dp_status);
-
- dp_drv->hpd_irq_toggled = dp_drv->hpd_irq_on !=
- dp_drv->alt_mode.dp_status.hpd_irq;
+ node = kzalloc(sizeof(*node), GFP_KERNEL);
+ node->vdo = *vdos;
- if (dp_drv->alt_mode.dp_status.hpd_irq) {
- pr_debug("Attention: hpd_irq high\n");
-
- if (dp_drv->power_on && dp_drv->hdcp.ops &&
- dp_drv->hdcp.ops->cp_irq)
- dp_drv->hdcp.ops->cp_irq(dp_drv->hdcp.data);
-
- if (!mdss_dp_process_hpd_irq_high(dp_drv))
- break;
- } else if (dp_drv->hpd_irq_toggled) {
- if (!mdss_dp_process_hpd_irq_low(dp_drv))
- break;
- }
-
- if (!dp_drv->alt_mode.dp_status.hpd_high) {
- pr_debug("Attention: HPD low\n");
- mdss_dp_update_cable_status(dp_drv, false);
- mdss_dp_notify_clients(dp_drv, false);
- pr_debug("Attention: Notified clients\n");
- break;
- }
-
- pr_debug("Attention: HPD high\n");
-
- mdss_dp_update_cable_status(dp_drv, true);
-
- dp_drv->alt_mode.current_state |= DP_STATUS_DONE;
-
- if (dp_drv->alt_mode.current_state & DP_CONFIGURE_DONE)
- mdss_dp_host_init(&dp_drv->panel_data);
- else
- dp_send_events(dp_drv, EV_USBPD_DP_CONFIGURE);
+ mutex_lock(&dp_drv->attention_lock);
+ list_add_tail(&node->list, &dp_drv->attention_head);
+ mutex_unlock(&dp_drv->attention_lock);
+ dp_send_events(dp_drv, EV_USBPD_ATTENTION);
break;
case DP_VDM_STATUS:
dp_drv->alt_mode.dp_status.response = *vdos;
@@ -2597,6 +2590,74 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd,
}
}
+static void mdss_dp_process_attention(struct mdss_dp_drv_pdata *dp_drv)
+{
+ dp_drv->hpd_irq_toggled = dp_drv->hpd_irq_on !=
+ dp_drv->alt_mode.dp_status.hpd_irq;
+
+ if (dp_drv->alt_mode.dp_status.hpd_irq) {
+ pr_debug("Attention: hpd_irq high\n");
+
+ if (dp_drv->power_on && dp_drv->hdcp.ops &&
+ dp_drv->hdcp.ops->cp_irq)
+ dp_drv->hdcp.ops->cp_irq(dp_drv->hdcp.data);
+
+ if (!mdss_dp_process_hpd_irq_high(dp_drv))
+ return;
+ } else if (dp_drv->hpd_irq_toggled) {
+ if (!mdss_dp_process_hpd_irq_low(dp_drv))
+ return;
+ }
+
+ if (!dp_drv->alt_mode.dp_status.hpd_high) {
+ pr_debug("Attention: HPD low\n");
+ mdss_dp_update_cable_status(dp_drv, false);
+ mdss_dp_notify_clients(dp_drv, false);
+ pr_debug("Attention: Notified clients\n");
+ return;
+ }
+
+ pr_debug("Attention: HPD high\n");
+
+ mdss_dp_update_cable_status(dp_drv, true);
+
+ dp_drv->alt_mode.current_state |= DP_STATUS_DONE;
+
+ if (dp_drv->alt_mode.current_state & DP_CONFIGURE_DONE)
+ mdss_dp_host_init(&dp_drv->panel_data);
+ else
+ dp_send_events(dp_drv, EV_USBPD_DP_CONFIGURE);
+
+ pr_debug("exit\n");
+}
+
+static void mdss_dp_handle_attention(struct mdss_dp_drv_pdata *dp)
+{
+ int i = 0;
+
+ while (!list_empty_careful(&dp->attention_head)) {
+ struct mdss_dp_attention_node *node;
+ u32 vdo;
+
+ pr_debug("processing item %d in the list\n", ++i);
+
+ mutex_lock(&dp->attention_lock);
+ node = list_first_entry(&dp->attention_head,
+ struct mdss_dp_attention_node, list);
+
+ vdo = node->vdo;
+ list_del(&node->list);
+ mutex_unlock(&dp->attention_lock);
+
+ kzfree(node);
+
+ dp->alt_mode.dp_status.response = vdo;
+ mdss_dp_usbpd_ext_dp_status(&dp->alt_mode.dp_status);
+ mdss_dp_process_attention(dp);
+ };
+
+}
+
static int mdss_dp_usbpd_setup(struct mdss_dp_drv_pdata *dp_drv)
{
int ret = 0;
@@ -2670,6 +2731,7 @@ static int mdss_dp_probe(struct platform_device *pdev)
dp_drv->mask2 = EDP_INTR_MASK2;
mutex_init(&dp_drv->emutex);
mutex_init(&dp_drv->pd_msg_mutex);
+ mutex_init(&dp_drv->attention_lock);
mutex_init(&dp_drv->hdcp_mutex);
spin_lock_init(&dp_drv->lock);
diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h
index e801eceeef1b..04abe9221acc 100644
--- a/drivers/video/fbdev/msm/mdss_dp.h
+++ b/drivers/video/fbdev/msm/mdss_dp.h
@@ -205,6 +205,7 @@ struct dp_alt_mode {
#define EV_USBPD_DP_CONFIGURE BIT(10)
#define EV_USBPD_CC_PIN_POLARITY BIT(11)
#define EV_USBPD_EXIT_MODE BIT(12)
+#define EV_USBPD_ATTENTION BIT(13)
/* dp state ctrl */
#define ST_TRAIN_PATTERN_1 BIT(0)
@@ -406,6 +407,7 @@ struct mdss_dp_drv_pdata {
struct dss_io_data ctrl_io;
struct dss_io_data phy_io;
struct dss_io_data tcsr_reg_io;
+ struct dss_io_data dp_cc_io;
struct dss_io_data qfprom_io;
struct dss_io_data hdcp_io;
int base_size;
@@ -454,6 +456,7 @@ struct mdss_dp_drv_pdata {
struct mutex aux_mutex;
struct mutex train_mutex;
struct mutex pd_msg_mutex;
+ struct mutex attention_lock;
struct mutex hdcp_mutex;
bool cable_connected;
u32 s3d_mode;
@@ -497,6 +500,8 @@ struct mdss_dp_drv_pdata {
struct dpcd_test_request test_data;
struct dpcd_sink_count sink_count;
+
+ struct list_head attention_head;
};
enum dp_lane_count {
diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c
index f9dba99a653d..b64518194926 100644
--- a/drivers/video/fbdev/msm/mdss_dp_aux.c
+++ b/drivers/video/fbdev/msm/mdss_dp_aux.c
@@ -514,7 +514,7 @@ char mdss_dp_gen_link_clk(struct mdss_panel_info *pinfo, char lane_cnt)
{
const u32 encoding_factx10 = 8;
const u32 ln_to_link_ratio = 10;
- u32 min_link_rate;
+ u32 min_link_rate, reminder = 0;
char calc_link_rate = 0;
pr_debug("clk_rate=%llu, bpp= %d, lane_cnt=%d\n",
@@ -531,9 +531,15 @@ char mdss_dp_gen_link_clk(struct mdss_panel_info *pinfo, char lane_cnt)
(lane_cnt * encoding_factx10));
min_link_rate /= ln_to_link_ratio;
min_link_rate = (min_link_rate * pinfo->bpp);
- min_link_rate = (u32)div_u64(min_link_rate * 10,
- DP_LINK_RATE_MULTIPLIER);
+ min_link_rate = (u32)div_u64_rem(min_link_rate * 10,
+ DP_LINK_RATE_MULTIPLIER, &reminder);
+ /*
+ * To avoid any fractional values,
+ * increment the min_link_rate
+ */
+ if (reminder)
+ min_link_rate += 1;
pr_debug("min_link_rate = %d\n", min_link_rate);
if (min_link_rate <= DP_LINK_RATE_162)
@@ -1647,6 +1653,8 @@ int mdss_dp_link_train(struct mdss_dp_drv_pdata *dp)
clear:
dp_clear_training_pattern(dp);
if (ret != -EINVAL) {
+ mdss_dp_config_misc_settings(&dp->ctrl_io,
+ &dp->panel_data.panel_info);
mdss_dp_setup_tr_unit(&dp->ctrl_io, dp->link_rate,
dp->lane_cnt, dp->vic);
mdss_dp_state_ctrl(&dp->ctrl_io, ST_SEND_VIDEO);
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c
index 2d24d8499105..86edc4492599 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.c
+++ b/drivers/video/fbdev/msm/mdss_dp_util.c
@@ -253,10 +253,48 @@ void mdss_dp_timing_cfg(struct dss_io_data *ctrl_io,
writel_relaxed(data, ctrl_io->base + DP_ACTIVE_HOR_VER);
}
-void mdss_dp_sw_mvid_nvid(struct dss_io_data *ctrl_io)
+void mdss_dp_sw_config_msa(struct dss_io_data *ctrl_io,
+ char lrate, struct dss_io_data *dp_cc_io)
{
- writel_relaxed(0x37, ctrl_io->base + DP_SOFTWARE_MVID);
- writel_relaxed(0x3c, ctrl_io->base + DP_SOFTWARE_NVID);
+ u32 pixel_m, pixel_n;
+ u32 mvid, nvid;
+
+ pixel_m = readl_relaxed(dp_cc_io->base + MMSS_DP_PIXEL_M);
+ pixel_n = readl_relaxed(dp_cc_io->base + MMSS_DP_PIXEL_N);
+ pr_debug("pixel_m=0x%x, pixel_n=0x%x\n",
+ pixel_m, pixel_n);
+
+ mvid = (pixel_m & 0xFFFF) * 5;
+ nvid = (0xFFFF & (~pixel_n)) + (pixel_m & 0xFFFF);
+ if (lrate == DP_LINK_RATE_540)
+ nvid = nvid * 2;
+ pr_debug("mvid=0x%x, nvid=0x%x\n", mvid, nvid);
+ writel_relaxed(mvid, ctrl_io->base + DP_SOFTWARE_MVID);
+ writel_relaxed(nvid, ctrl_io->base + DP_SOFTWARE_NVID);
+}
+
+void mdss_dp_config_misc_settings(struct dss_io_data *ctrl_io,
+ struct mdss_panel_info *pinfo)
+{
+ u32 bpp = pinfo->bpp;
+ u32 misc_val = 0x0;
+
+ switch (bpp) {
+ case 18:
+ misc_val |= (0x0 << 5);
+ break;
+ case 30:
+ misc_val |= (0x2 << 5);
+ break;
+ case 24:
+ default:
+ misc_val |= (0x1 << 5);
+ }
+
+ misc_val |= BIT(0); /* Configure clock to synchronous mode */
+
+ pr_debug("Misc settings = 0x%x\n", misc_val);
+ writel_relaxed(misc_val, ctrl_io->base + DP_MISC1_MISC0);
}
void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate,
@@ -267,8 +305,6 @@ void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate,
u32 valid_boundary2 = 0x0;
struct dp_vc_tu_mapping_table const *tu_entry = tu_table;
- writel_relaxed(0x21, ctrl_io->base + DP_MISC1_MISC0);
-
for (; tu_entry != tu_table + ARRAY_SIZE(tu_table); ++tu_entry) {
if ((tu_entry->vic == res) &&
(tu_entry->lanes == ln_cnt) &&
@@ -454,8 +490,14 @@ u32 mdss_dp_usbpd_gen_config_pkt(struct mdss_dp_drv_pdata *dp)
pin_cfg = dp->alt_mode.dp_cap.dlink_pin_config;
for (pin = PIN_ASSIGNMENT_A; pin < PIN_ASSIGNMENT_MAX; pin++) {
- if (pin_cfg & BIT(pin))
- break;
+ if (pin_cfg & BIT(pin)) {
+ if (dp->alt_mode.dp_status.multi_func) {
+ if (pin == PIN_ASSIGNMENT_D)
+ break;
+ } else {
+ break;
+ }
+ }
}
if (pin == PIN_ASSIGNMENT_MAX)
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.h b/drivers/video/fbdev/msm/mdss_dp_util.h
index 334c0071050d..4b28d98177be 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.h
+++ b/drivers/video/fbdev/msm/mdss_dp_util.h
@@ -164,6 +164,12 @@
#define TCSR_USB3_DP_PHYMODE 0x48
#define EDID_START_ADDRESS 0x50
+/* DP MMSS_CC registers */
+#define MMSS_DP_LINK_CMD_RCGR 0x0000
+#define MMSS_DP_LINK_CFG_RCGR 0x0004
+#define MMSS_DP_PIXEL_M 0x0048
+#define MMSS_DP_PIXEL_N 0x004C
+
/* DP HDCP 1.3 registers */
#define DP_HDCP_CTRL (0x0A0)
#define DP_HDCP_STATUS (0x0A4)
@@ -271,6 +277,8 @@ void mdss_dp_switch_usb3_phy_to_dp_mode(struct dss_io_data *tcsr_reg_io);
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);
+void mdss_dp_config_misc_settings(struct dss_io_data *ctrl_io,
+ struct mdss_panel_info *pinfo);
void mdss_dp_phy_aux_setup(struct dss_io_data *phy_io);
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);
@@ -285,7 +293,8 @@ void mdss_dp_state_ctrl(struct dss_io_data *ctrl_io, u32 data);
int mdss_dp_irq_setup(struct mdss_dp_drv_pdata *dp_drv);
void mdss_dp_irq_enable(struct mdss_dp_drv_pdata *dp_drv);
void mdss_dp_irq_disable(struct mdss_dp_drv_pdata *dp_drv);
-void mdss_dp_sw_mvid_nvid(struct dss_io_data *ctrl_io);
+void mdss_dp_sw_config_msa(struct dss_io_data *ctrl_io,
+ char lrate, struct dss_io_data *dp_cc_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);
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index cf7a398c13ce..8dccab8a81be 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -2985,6 +2985,12 @@ static int mdss_dsi_cont_splash_config(struct mdss_panel_info *pinfo,
mdss_dsi_panel_pwm_enable(ctrl_pdata);
ctrl_pdata->ctrl_state |= (CTRL_STATE_PANEL_INIT |
CTRL_STATE_MDP_ACTIVE | CTRL_STATE_DSI_ACTIVE);
+
+ /*
+ * MDP client removes this extra vote during splash reconfigure
+ * for command mode panel from interface. DSI removes the vote
+ * during suspend-resume for video mode panel.
+ */
if (ctrl_pdata->panel_data.panel_info.type == MIPI_CMD_PANEL)
clk_handle = ctrl_pdata->mdp_clk_handle;
else
diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h
index 3536cb2d294d..3a347681f434 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.h
+++ b/drivers/video/fbdev/msm/mdss_dsi.h
@@ -557,7 +557,8 @@ struct mdss_dsi_ctrl_pdata {
void *clk_mngr;
void *dsi_clk_handle;
void *mdp_clk_handle;
- int m_vote_cnt;
+ int m_dsi_vote_cnt;
+ int m_mdp_vote_cnt;
/* debugfs structure */
struct mdss_dsi_debugfs_info *debugfs_info;
diff --git a/drivers/video/fbdev/msm/mdss_dsi_clk.c b/drivers/video/fbdev/msm/mdss_dsi_clk.c
index a7d1c251fab0..755d6092ea11 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_clk.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_clk.c
@@ -795,8 +795,29 @@ error:
return rc;
}
+bool is_dsi_clk_in_ecg_state(void *client)
+{
+ struct mdss_dsi_clk_client_info *c = client;
+ struct mdss_dsi_clk_mngr *mngr;
+ bool is_ecg = false;
+
+ if (!client) {
+ pr_err("Invalid client params\n");
+ goto end;
+ }
+
+ mngr = c->mngr;
+
+ mutex_lock(&mngr->clk_mutex);
+ is_ecg = (c->core_clk_state == MDSS_DSI_CLK_EARLY_GATE);
+ mutex_unlock(&mngr->clk_mutex);
+
+end:
+ return is_ecg;
+}
+
int mdss_dsi_clk_req_state(void *client, enum mdss_dsi_clk_type clk,
- enum mdss_dsi_clk_state state)
+ enum mdss_dsi_clk_state state, u32 index)
{
int rc = 0;
struct mdss_dsi_clk_client_info *c = client;
@@ -817,7 +838,7 @@ int mdss_dsi_clk_req_state(void *client, enum mdss_dsi_clk_type clk,
c->name, mngr->name, clk, state, c->core_clk_state,
c->link_clk_state);
- MDSS_XLOG(clk, state, c->core_clk_state, c->link_clk_state);
+ MDSS_XLOG(index, clk, state, c->core_clk_state, c->link_clk_state);
/*
* Refcount handling rules:
* 1. Increment refcount whenever ON is called
@@ -883,7 +904,7 @@ int mdss_dsi_clk_req_state(void *client, enum mdss_dsi_clk_type clk,
pr_debug("[%s]%s: change=%d, Core (ref=%d, state=%d), Link (ref=%d, state=%d)\n",
c->name, mngr->name, changed, c->core_refcount,
c->core_clk_state, c->link_refcount, c->link_clk_state);
- MDSS_XLOG(clk, state, c->core_clk_state, c->link_clk_state);
+ MDSS_XLOG(index, clk, state, c->core_clk_state, c->link_clk_state);
if (changed) {
rc = dsi_recheck_clk_state(mngr);
diff --git a/drivers/video/fbdev/msm/mdss_dsi_clk.h b/drivers/video/fbdev/msm/mdss_dsi_clk.h
index 9fe45254fe6d..0b88ddb57166 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_clk.h
+++ b/drivers/video/fbdev/msm/mdss_dsi_clk.h
@@ -197,6 +197,7 @@ int mdss_dsi_clk_deregister(void *client);
* @client: client handle.
* @clk: Type of clock requested (enum mdss_dsi_clk_type).
* @state: clock state requested.
+ * @index: controller index.
*
* This routine is used to request a new clock state for a specific clock. If
* turning ON the clocks, this guarantees that clocks will be on before
@@ -206,7 +207,7 @@ int mdss_dsi_clk_deregister(void *client);
* @return: error code.
*/
int mdss_dsi_clk_req_state(void *client, enum mdss_dsi_clk_type clk,
- enum mdss_dsi_clk_state state);
+ enum mdss_dsi_clk_state state, u32 index);
/**
* mdss_dsi_clk_set_link_rate() - set clock rate for link clocks
@@ -238,4 +239,16 @@ int mdss_dsi_clk_set_link_rate(void *client, enum mdss_dsi_link_clk_type clk,
* @return:error code.
*/
int mdss_dsi_clk_force_toggle(void *client, u32 clk);
+
+/**
+ * is_dsi_clk_in_ecg_state() - Checks the current state of clocks
+ * @client: client handle.
+ *
+ * This routine returns checks the clocks status for client and return
+ * success code based on it.
+ *
+ * @return:true: if clocks are in ECG state
+ * false: for all other cases
+ */
+bool is_dsi_clk_in_ecg_state(void *client);
#endif /* _MDSS_DSI_CLK_H_ */
diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c
index c9168242da60..5f8b45413e32 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_host.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_host.c
@@ -2811,12 +2811,6 @@ static int dsi_event_thread(void *data)
pr_debug("%s: Handling underflow event\n",
__func__);
__dsi_fifo_error_handler(ctrl, true);
- } else {
- pr_err("%s: ctrl recovery not defined\n",
- __func__);
- MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0_ctrl",
- "dsi0_phy", "dsi1_ctrl", "dsi1_phy", "vbif",
- "vbif_nrt", "dbg_bus", "vbif_dbg_bus", "panic");
}
mutex_unlock(&ctrl->mutex);
}
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index 08e06c75522a..d528305af798 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -233,9 +233,11 @@ static int mdss_fb_notify_update(struct msm_fb_data_type *mfd,
}
} else if (notify == NOTIFY_UPDATE_STOP) {
mutex_lock(&mfd->update.lock);
- if (mfd->update.init_done)
+ if (mfd->update.init_done) {
+ mutex_unlock(&mfd->update.lock);
+ mutex_lock(&mfd->no_update.lock);
reinit_completion(&mfd->no_update.comp);
- else {
+ } else {
mutex_unlock(&mfd->update.lock);
pr_err("notify update stop called without init\n");
return -EINVAL;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index 9ed44937efe6..6b71025229a0 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -4227,9 +4227,11 @@ int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff)
return 0;
}
- ret = mdss_mdp_ctl_setup(ctl);
- if (ret)
- return ret;
+ if (mdss_mdp_ctl_is_power_off(ctl)) {
+ ret = mdss_mdp_ctl_setup(ctl);
+ if (ret)
+ return ret;
+ }
sctl = mdss_mdp_get_split_ctl(ctl);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
index f08af5d6edd3..a71c7254de7c 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
@@ -335,6 +335,57 @@ static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_mixer *mixer,
return 0;
}
+static bool __disable_rd_ptr_from_te(char __iomem *pingpong_base)
+{
+ u32 cfg;
+ bool disabled;
+
+ cfg = mdss_mdp_pingpong_read(pingpong_base,
+ MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC);
+
+ disabled = BIT(20) & cfg;
+ cfg &= ~BIT(20);
+ mdss_mdp_pingpong_write(pingpong_base,
+ MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC, cfg);
+
+ return disabled;
+}
+
+static inline void __enable_rd_ptr_from_te(char __iomem *pingpong_base)
+{
+ u32 cfg;
+
+ cfg = mdss_mdp_pingpong_read(pingpong_base,
+ MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC);
+ cfg |= BIT(20);
+ mdss_mdp_pingpong_write(pingpong_base,
+ MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC, cfg);
+}
+
+/*
+* __disable_autorefresh - disables autorefresh feature in the hw.
+*
+* To disable autorefresh, driver needs to make sure no transactions are
+* on-going; for ensuring this, driver must:
+*
+* 1. Disable listening to the external TE (this gives extra time before
+* trigger next transaction).
+* 2. Wait for any on-going transaction (wait for ping pong done interrupt).
+* 3. Disable auto-refresh.
+* 4. Re-enable listening to the external panel TE.
+*
+* So it is responsability of the caller of this function to only call to disable
+* autorefresh if no hw transaction is on-going (wait for ping pong) and if
+* the listening for the external TE is disabled in the tear check logic (this
+* to prevent any race conditions with the hw), as mentioned in the above
+* steps.
+*/
+static inline void __disable_autorefresh(char __iomem *pingpong_base)
+{
+ mdss_mdp_pingpong_write(pingpong_base,
+ MDSS_MDP_REG_PP_AUTOREFRESH_CONFIG, 0x0);
+}
+
static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx,
bool locked)
{
@@ -342,7 +393,7 @@ static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx,
struct mdss_mdp_mixer *mixer = NULL, *mixer_right = NULL;
struct mdss_mdp_ctl *ctl = ctx->ctl;
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
- u32 offset = 0;
+ bool rd_ptr_disabled = false;
mixer = mdss_mdp_mixer_get(ctl, MDSS_MDP_MIXER_MUX_LEFT);
if (mixer) {
@@ -352,21 +403,32 @@ static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx,
*/
if (mdss_mdp_pingpong_read(mixer->pingpong_base,
MDSS_MDP_REG_PP_AUTOREFRESH_CONFIG) & BIT(31)) {
- offset = MDSS_MDP_REG_PP_AUTOREFRESH_CONFIG;
+
+ /* 1. disable rd pointer from the external te */
+ rd_ptr_disabled =
+ __disable_rd_ptr_from_te(mixer->pingpong_base);
+
+ /* 2. disable autorefresh */
if (is_pingpong_split(ctl->mfd))
- writel_relaxed(0x0,
- (mdata->slave_pingpong_base + offset));
+ __disable_autorefresh(
+ mdata->slave_pingpong_base);
+
if (is_split_lm(ctl->mfd)) {
- mixer_right =
- mdss_mdp_mixer_get(ctl,
- MDSS_MDP_MIXER_MUX_RIGHT);
+ mixer_right = mdss_mdp_mixer_get(ctl,
+ MDSS_MDP_MIXER_MUX_RIGHT);
+
if (mixer_right)
- writel_relaxed(0x0,
- (mixer_right->pingpong_base + offset));
+ __disable_autorefresh(
+ mixer_right->pingpong_base);
}
- mdss_mdp_pingpong_write(mixer->pingpong_base,
- MDSS_MDP_REG_PP_AUTOREFRESH_CONFIG, 0x0);
+
+ __disable_autorefresh(mixer->pingpong_base);
pr_debug("%s: disabling auto refresh\n", __func__);
+
+ /* 2. re-enable rd pointer from te (if was enabled) */
+ if (rd_ptr_disabled)
+ __enable_rd_ptr_from_te(mixer->pingpong_base);
+
}
rc = mdss_mdp_cmd_tearcheck_cfg(mixer, ctx, locked);
if (rc)
@@ -991,6 +1053,7 @@ static void mdss_mdp_cmd_readptr_done(void *arg)
vsync_time = ktime_get();
ctl->vsync_cnt++;
MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt));
+ trace_mdp_cmd_readptr_done(ctl->num, atomic_read(&ctx->koff_cnt));
complete_all(&ctx->rdptr_done);
/* If caller is waiting for the read pointer, notify. */
@@ -2364,7 +2427,6 @@ static void mdss_mdp_cmd_pre_programming(struct mdss_mdp_ctl *mctl)
struct mdss_mdp_cmd_ctx *ctx = mctl->intf_ctx[MASTER_CTX];
char __iomem *pp_base;
u32 autorefresh_state;
- u32 cfg;
if (!mctl->is_master)
return;
@@ -2384,11 +2446,8 @@ static void mdss_mdp_cmd_pre_programming(struct mdss_mdp_ctl *mctl)
* instruct MDP to ignore the panel TE so the next auto-refresh
* is delayed until flush bits are set.
*/
- cfg = mdss_mdp_pingpong_read(pp_base,
- MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC);
- cfg &= ~BIT(20);
- mdss_mdp_pingpong_write(pp_base,
- MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC, cfg);
+ __disable_rd_ptr_from_te(pp_base);
+
ctx->ignore_external_te = true;
}
@@ -2400,7 +2459,6 @@ static void mdss_mdp_cmd_post_programming(struct mdss_mdp_ctl *mctl)
{
struct mdss_mdp_cmd_ctx *ctx = mctl->intf_ctx[MASTER_CTX];
char __iomem *pp_base;
- u32 cfg;
if (!mctl->is_master)
return;
@@ -2419,11 +2477,8 @@ static void mdss_mdp_cmd_post_programming(struct mdss_mdp_ctl *mctl)
pp_base = mctl->mixer_left->pingpong_base;
/* enable MDP to listen to the TE */
- cfg = mdss_mdp_pingpong_read(pp_base,
- MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC);
- cfg |= BIT(20);
- mdss_mdp_pingpong_write(pp_base,
- MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC, cfg);
+ __enable_rd_ptr_from_te(pp_base);
+
ctx->ignore_external_te = false;
}
}
@@ -2675,11 +2730,10 @@ static int mdss_mdp_disable_autorefresh(struct mdss_mdp_ctl *ctl,
mdss_mdp_cmd_wait4_autorefresh_pp(sctl);
/* disable autorefresh */
- mdss_mdp_pingpong_write(pp_base, MDSS_MDP_REG_PP_AUTOREFRESH_CONFIG, 0);
+ __disable_autorefresh(pp_base);
if (is_pingpong_split(ctl->mfd))
- mdss_mdp_pingpong_write(mdata->slave_pingpong_base,
- MDSS_MDP_REG_PP_AUTOREFRESH_CONFIG, 0);
+ __disable_autorefresh(mdata->slave_pingpong_base);
ctx->autorefresh_state = MDP_AUTOREFRESH_OFF;
ctx->autorefresh_frame_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 048e5fce30c6..70b36a08d5ca 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
@@ -960,7 +960,7 @@ static int mdss_mdp_video_intfs_stop(struct mdss_mdp_ctl *ctl,
pr_err("Intf %d not in use\n", (inum + MDSS_MDP_INTF0));
return -ENODEV;
}
- pr_debug("stop ctl=%d video Intf #%d base=%p", ctl->num, ctx->intf_num,
+ pr_debug("stop ctl=%d video Intf #%d base=%pK", ctl->num, ctx->intf_num,
ctx->base);
ret = mdss_mdp_video_ctx_stop(ctl, pinfo, ctx);
@@ -978,7 +978,7 @@ static int mdss_mdp_video_intfs_stop(struct mdss_mdp_ctl *ctl,
pr_err("Intf %d not in use\n", (inum + MDSS_MDP_INTF0));
return -ENODEV;
}
- pr_debug("stop ctl=%d video Intf #%d base=%p", ctl->num,
+ pr_debug("stop ctl=%d video Intf #%d base=%pK", ctl->num,
sctx->intf_num, sctx->base);
ret = mdss_mdp_video_ctx_stop(ctl, pinfo, sctx);
@@ -2021,7 +2021,7 @@ static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl,
(inum + MDSS_MDP_INTF0));
return -EBUSY;
}
- pr_debug("video Intf #%d base=%p", ctx->intf_num, ctx->base);
+ pr_debug("video Intf #%d base=%pK", ctx->intf_num, ctx->base);
ctx->ref_cnt++;
} else {
pr_err("Invalid intf number: %d\n", (inum + MDSS_MDP_INTF0));
@@ -2054,7 +2054,7 @@ static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl,
(inum + MDSS_MDP_INTF0));
return -EBUSY;
}
- pr_debug("video Intf #%d base=%p", ctx->intf_num, ctx->base);
+ pr_debug("video Intf #%d base=%pK", ctx->intf_num, ctx->base);
ctx->ref_cnt++;
ctl->intf_ctx[SLAVE_CTX] = ctx;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_layer.c b/drivers/video/fbdev/msm/mdss_mdp_layer.c
index 20fcc26bb4bf..73350b3a5a6f 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_layer.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_layer.c
@@ -852,7 +852,7 @@ static int __validate_layer_reconfig(struct mdp_input_layer *layer,
*/
if (pipe->csc_coeff_set != layer->color_space) {
src_fmt = mdss_mdp_get_format_params(layer->buffer.format);
- if (pipe->src_fmt->is_yuv && src_fmt->is_yuv) {
+ if (pipe->src_fmt->is_yuv && src_fmt && src_fmt->is_yuv) {
status = -EPERM;
pr_err("csc change is not permitted on used pipe\n");
}
@@ -2470,16 +2470,20 @@ validate_exit:
mutex_lock(&mdp5_data->list_lock);
list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_used, list) {
if (IS_ERR_VALUE(ret)) {
- if ((pipe->ndx & rec_release_ndx[0]) ||
- (pipe->ndx & rec_release_ndx[1])) {
+ if (((pipe->ndx & rec_release_ndx[0]) &&
+ (pipe->multirect.num == 0)) ||
+ ((pipe->ndx & rec_release_ndx[1]) &&
+ (pipe->multirect.num == 1))) {
mdss_mdp_smp_unreserve(pipe);
pipe->params_changed = 0;
pipe->dirty = true;
if (!list_empty(&pipe->list))
list_del_init(&pipe->list);
mdss_mdp_pipe_destroy(pipe);
- } else if ((pipe->ndx & rec_destroy_ndx[0]) ||
- (pipe->ndx & rec_destroy_ndx[1])) {
+ } else if (((pipe->ndx & rec_destroy_ndx[0]) &&
+ (pipe->multirect.num == 0)) ||
+ ((pipe->ndx & rec_destroy_ndx[1]) &&
+ (pipe->multirect.num == 1))) {
/*
* cleanup/destroy list pipes should move back
* to destroy list. Next/current kickoff cycle
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index 664850a1a617..298b8743f0a6 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -1533,7 +1533,7 @@ static int __overlay_queue_pipes(struct msm_fb_data_type *mfd)
}
break;
default:
- pr_err("invalid state of buf %p=%d\n",
+ pr_err("invalid state of buf %pK=%d\n",
buf, buf->state);
BUG();
break;
@@ -2120,8 +2120,10 @@ static int __overlay_secure_ctrl(struct msm_fb_data_type *mfd)
int ret = 0;
int sd_in_pipe = 0;
int sc_in_pipe = 0;
+ u64 pipes_flags = 0;
list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
+ pipes_flags |= pipe->flags;
if (pipe->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION) {
sd_in_pipe = 1;
pr_debug("Secure pipe: %u : %16llx\n",
@@ -2133,34 +2135,54 @@ static int __overlay_secure_ctrl(struct msm_fb_data_type *mfd)
}
}
- if ((!sd_in_pipe && !mdp5_data->sd_enabled) ||
- (sd_in_pipe && mdp5_data->sd_enabled) ||
- (!sc_in_pipe && !mdp5_data->sc_enabled) ||
+ MDSS_XLOG(sd_in_pipe, sc_in_pipe, pipes_flags,
+ mdp5_data->sc_enabled, mdp5_data->sd_enabled);
+ pr_debug("sd:%d sd_in_pipe:%d sc:%d sc_in_pipe:%d flags:0x%llx\n",
+ mdp5_data->sd_enabled, sd_in_pipe,
+ mdp5_data->sc_enabled, sc_in_pipe, pipes_flags);
+
+ /*
+ * Return early in only two conditions:
+ * 1. All the features are already disabled and state remains
+ * disabled for the pipes.
+ * 2. One of the features is already enabled and state remains
+ * enabled for the pipes.
+ */
+ if (!sd_in_pipe && !mdp5_data->sd_enabled &&
+ !sc_in_pipe && !mdp5_data->sc_enabled)
+ return ret;
+ else if ((sd_in_pipe && mdp5_data->sd_enabled) ||
(sc_in_pipe && mdp5_data->sc_enabled))
return ret;
/* Secure Display */
if (!mdp5_data->sd_enabled && sd_in_pipe) {
if (!mdss_get_sd_client_cnt()) {
+ MDSS_XLOG(0x11);
/*wait for ping pong done */
if (ctl->ops.wait_pingpong)
mdss_mdp_display_wait4pingpong(ctl, true);
ret = mdss_mdp_secure_session_ctrl(1,
MDP_SECURE_DISPLAY_OVERLAY_SESSION);
- if (ret)
+ if (ret) {
+ pr_err("secure display enable fail:%d", ret);
return ret;
+ }
}
mdp5_data->sd_enabled = 1;
mdss_update_sd_client(mdp5_data->mdata, true);
} else if (mdp5_data->sd_enabled && !sd_in_pipe) {
/* disable the secure display on last client */
if (mdss_get_sd_client_cnt() == 1) {
+ MDSS_XLOG(0x22);
if (ctl->ops.wait_pingpong)
mdss_mdp_display_wait4pingpong(ctl, true);
ret = mdss_mdp_secure_session_ctrl(0,
MDP_SECURE_DISPLAY_OVERLAY_SESSION);
- if (ret)
+ if (ret) {
+ pr_err("secure display disable fail:%d\n", ret);
return ret;
+ }
}
mdss_update_sd_client(mdp5_data->mdata, false);
mdp5_data->sd_enabled = 0;
@@ -2169,29 +2191,36 @@ static int __overlay_secure_ctrl(struct msm_fb_data_type *mfd)
/* Secure Camera */
if (!mdp5_data->sc_enabled && sc_in_pipe) {
if (!mdss_get_sc_client_cnt()) {
+ MDSS_XLOG(0x33);
if (ctl->ops.wait_pingpong)
mdss_mdp_display_wait4pingpong(ctl, true);
ret = mdss_mdp_secure_session_ctrl(1,
MDP_SECURE_CAMERA_OVERLAY_SESSION);
- if (ret)
+ if (ret) {
+ pr_err("secure camera enable fail:%d\n", ret);
return ret;
+ }
}
mdp5_data->sc_enabled = 1;
mdss_update_sc_client(mdp5_data->mdata, true);
} else if (mdp5_data->sc_enabled && !sc_in_pipe) {
/* disable the secure camera on last client */
if (mdss_get_sc_client_cnt() == 1) {
+ MDSS_XLOG(0x44);
if (ctl->ops.wait_pingpong)
mdss_mdp_display_wait4pingpong(ctl, true);
ret = mdss_mdp_secure_session_ctrl(0,
MDP_SECURE_CAMERA_OVERLAY_SESSION);
- if (ret)
+ if (ret) {
+ pr_err("secure camera disable fail:%d\n", ret);
return ret;
+ }
}
mdss_update_sc_client(mdp5_data->mdata, false);
mdp5_data->sc_enabled = 0;
}
+ MDSS_XLOG(ret);
return ret;
}
@@ -5430,6 +5459,7 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
mdss_mdp_overlay_kickoff(mfd, NULL);
}
+ctl_stop:
/*
* If retire fences are still active wait for a vsync time
* for retire fence to be updated.
@@ -5460,7 +5490,6 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
flush_work(&mdp5_data->retire_work);
}
-ctl_stop:
mutex_lock(&mdp5_data->ov_lock);
/* set the correct pipe_mapped before ctl_stop */
mdss_mdp_mixer_update_pipe_map(mdp5_data->ctl,
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
index e370a80ad998..bcf5309993b9 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
@@ -1340,10 +1340,11 @@ static struct mdss_mdp_pipe *__pipe_lookup(struct mdss_mdp_pipe *pipe_list,
bool (*cmp)(struct mdss_mdp_pipe *, void *), void *data)
{
struct mdss_mdp_pipe *pipe;
- int i, j;
+ int i, j, max_rects;
for (i = 0, pipe = pipe_list; i < count; i++) {
- for (j = 0; j < pipe->multirect.max_rects; j++, pipe++)
+ max_rects = pipe->multirect.max_rects;
+ for (j = 0; j < max_rects; j++, pipe++)
if ((rect_num == pipe->multirect.num) &&
cmp(pipe, data))
return pipe;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c
index f79212ea740d..c6bef7c22193 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c
@@ -2906,7 +2906,7 @@ int mdss_mdp_pp_resume(struct msm_fb_data_type *mfd)
mfd->index);
return 0;
} else if (ret || !ad) {
- pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n",
+ pr_err("Failed to get ad info: ret = %d, ad = 0x%pK\n",
ret, ad);
return ret;
}
@@ -3250,7 +3250,7 @@ static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out,
mfd->index);
return 0;
} else if (ret || !ad) {
- pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n",
+ pr_err("Failed to get ad info: ret = %d, ad = 0x%pK\n",
ret, ad);
return ret;
}
@@ -5754,7 +5754,7 @@ static int pp_ad_invalidate_input(struct msm_fb_data_type *mfd)
mfd->index);
return 0;
} else if (ret || !ad) {
- pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n",
+ pr_err("Failed to get ad info: ret = %d, ad = 0x%pK\n",
ret, ad);
return ret;
}
@@ -5789,7 +5789,7 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd,
mfd->index);
return ret;
} else if (ret || !ad) {
- pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n",
+ pr_err("Failed to get ad info: ret = %d, ad = 0x%pK\n",
ret, ad);
return ret;
}
@@ -5929,7 +5929,7 @@ int mdss_mdp_ad_input(struct msm_fb_data_type *mfd,
mfd->index);
return ret;
} else if (ret || !ad) {
- pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n",
+ pr_err("Failed to get ad info: ret = %d, ad = 0x%pK\n",
ret, ad);
return ret;
}
@@ -6298,7 +6298,7 @@ static int mdss_mdp_ad_ipc_reset(struct msm_fb_data_type *mfd)
mfd->index);
return 0;
} else if (ret || !ad) {
- pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n",
+ pr_err("Failed to get ad info: ret = %d, ad = 0x%pK\n",
ret, ad);
return ret;
}
@@ -6339,7 +6339,7 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd)
mfd->index);
return 0;
} else if (ret || !ad) {
- pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n",
+ pr_err("Failed to get ad info: ret = %d, ad = 0x%pK\n",
ret, ad);
return ret;
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c b/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c
index 5bd627853c59..e51cf44c2de2 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c
@@ -367,7 +367,7 @@ int pp_dither_cache_params(struct mdp_dither_cfg_data *config,
{
int ret = 0;
if (!config || !mdss_pp_res) {
- pr_err("invalid param config %pi pp_res %pK\n",
+ pr_err("invalid param config %pK pp_res %pK\n",
config, mdss_pp_res);
return -EINVAL;
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_trace.h b/drivers/video/fbdev/msm/mdss_mdp_trace.h
index 648e4fcd1cd2..b79b4c70f5dc 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_trace.h
+++ b/drivers/video/fbdev/msm/mdss_mdp_trace.h
@@ -372,6 +372,22 @@ TRACE_EVENT(mdp_cmd_pingpong_done,
__entry->koff_cnt)
);
+TRACE_EVENT(mdp_cmd_readptr_done,
+ TP_PROTO(u32 ctl_num, int koff_cnt),
+ TP_ARGS(ctl_num, koff_cnt),
+ TP_STRUCT__entry(
+ __field(u32, ctl_num)
+ __field(int, koff_cnt)
+ ),
+ TP_fast_assign(
+ __entry->ctl_num = ctl_num;
+ __entry->koff_cnt = koff_cnt;
+ ),
+ TP_printk("ctl num:%d kickoff:%d",
+ __entry->ctl_num,
+ __entry->koff_cnt)
+);
+
TRACE_EVENT(mdp_cmd_release_bw,
TP_PROTO(u32 ctl_num),
TP_ARGS(ctl_num),
diff --git a/drivers/video/fbdev/msm/mdss_util.c b/drivers/video/fbdev/msm/mdss_util.c
index d2610ff80878..65941601cfdc 100644
--- a/drivers/video/fbdev/msm/mdss_util.c
+++ b/drivers/video/fbdev/msm/mdss_util.c
@@ -23,6 +23,7 @@ int mdss_register_irq(struct mdss_hw *hw)
{
unsigned long irq_flags;
u32 ndx_bit;
+ bool err = false;
if (!hw || hw->hw_ndx >= MDSS_MAX_HW_BLK)
return -EINVAL;
@@ -33,10 +34,12 @@ int mdss_register_irq(struct mdss_hw *hw)
if (!mdss_irq_handlers[hw->hw_ndx])
mdss_irq_handlers[hw->hw_ndx] = hw;
else
- pr_err("panel %d's irq at %pK is already registered\n",
- hw->hw_ndx, hw->irq_handler);
+ err = true;
spin_unlock_irqrestore(&mdss_lock, irq_flags);
+ if (err)
+ pr_err("panel %d's irq at %pK is already registered\n",
+ hw->hw_ndx, hw->irq_handler);
return 0;
}
@@ -76,6 +79,7 @@ void mdss_disable_irq(struct mdss_hw *hw)
{
unsigned long irq_flags;
u32 ndx_bit;
+ bool err = false;
if (hw->hw_ndx >= MDSS_MAX_HW_BLK)
return;
@@ -87,7 +91,7 @@ void mdss_disable_irq(struct mdss_hw *hw)
spin_lock_irqsave(&mdss_lock, irq_flags);
if (!(hw->irq_info->irq_mask & ndx_bit)) {
- pr_warn("MDSS HW ndx=%d is NOT set\n", hw->hw_ndx);
+ err = true;
} else {
hw->irq_info->irq_mask &= ~ndx_bit;
if (hw->irq_info->irq_mask == 0) {
@@ -96,12 +100,16 @@ void mdss_disable_irq(struct mdss_hw *hw)
}
}
spin_unlock_irqrestore(&mdss_lock, irq_flags);
+
+ if (err)
+ pr_warn("MDSS HW ndx=%d is NOT set\n", hw->hw_ndx);
}
/* called from interrupt context */
void mdss_disable_irq_nosync(struct mdss_hw *hw)
{
u32 ndx_bit;
+ bool err = false;
if (hw->hw_ndx >= MDSS_MAX_HW_BLK)
return;
@@ -113,7 +121,7 @@ void mdss_disable_irq_nosync(struct mdss_hw *hw)
spin_lock(&mdss_lock);
if (!(hw->irq_info->irq_mask & ndx_bit)) {
- pr_warn("MDSS HW ndx=%d is NOT set\n", hw->hw_ndx);
+ err = true;
} else {
hw->irq_info->irq_mask &= ~ndx_bit;
if (hw->irq_info->irq_mask == 0) {
@@ -122,6 +130,9 @@ void mdss_disable_irq_nosync(struct mdss_hw *hw)
}
}
spin_unlock(&mdss_lock);
+
+ if (err)
+ pr_warn("MDSS HW ndx=%d is NOT set\n", hw->hw_ndx);
}
int mdss_irq_dispatch(u32 hw_ndx, int irq, void *ptr)
@@ -176,6 +187,7 @@ void mdss_disable_irq_wake(struct mdss_hw *hw)
{
unsigned long irq_flags;
u32 ndx_bit;
+ bool err = false;
if (hw->hw_ndx >= MDSS_MAX_HW_BLK)
return;
@@ -188,7 +200,7 @@ void mdss_disable_irq_wake(struct mdss_hw *hw)
spin_lock_irqsave(&mdss_lock, irq_flags);
if (!(hw->irq_info->irq_wake_mask & ndx_bit)) {
- pr_warn("MDSS HW ndx=%d is NOT set\n", hw->hw_ndx);
+ err = true;
} else {
hw->irq_info->irq_wake_mask &= ~ndx_bit;
if (hw->irq_info->irq_wake_ena) {
@@ -197,6 +209,9 @@ void mdss_disable_irq_wake(struct mdss_hw *hw)
}
}
spin_unlock_irqrestore(&mdss_lock, irq_flags);
+
+ if (err)
+ pr_warn("MDSS HW ndx=%d is NOT set\n", hw->hw_ndx);
}
struct mdss_util_intf mdss_util = {
diff --git a/drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d.c b/drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d.c
index 20d48575f323..4c9045d6a2a7 100644
--- a/drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d.c
+++ b/drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d.c
@@ -1118,7 +1118,7 @@ static void tx_prune_dtd_list(struct edid_3d_data_t *mhl_edid_3d_data,
if ((0 != p_desc->dtd.pixel_clock_low) ||
(0 != p_desc->dtd.pixel_clock_high)) {
MHL_TX_EDID_INFO(
- "pix clock non-zero p_desc:%p", p_desc)
+ "pix clock non-zero p_desc:%pK", p_desc)
if ((0 == p_desc->dtd.horz_active_7_0) &&
(0 == p_desc->dtd.horz_active_blanking_high.
horz_active_11_8)) {
@@ -1722,9 +1722,10 @@ static void prune_svd_list(
("\n\nInvalid extension size\n\n"));
while (pb_src < pb_limit) {
MHL_TX_EDID_INFO(
- "moving data up %p(0x%02X) "
- "<- %p(0x%02X)\n",
- pb_dest, (uint16_t)*pb_dest,
+ "moving data up %pK(0x%02X) ",
+ pb_dest, (uint16_t)*pb_dest);
+ MHL_TX_EDID_INFO(
+ "<- %pK(0x%02X)\n",
pb_src, (uint16_t)*pb_src);
*pb_dest++ = *pb_src++;
}
diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
index b5b5a026733e..0c43a2642ede 100644
--- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c
+++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
@@ -2081,7 +2081,11 @@ int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, void *clk_handle,
{
int rc = 0;
struct mdss_dsi_ctrl_pdata *mctrl = NULL;
- int i;
+ int i, *vote_cnt;
+
+ void *m_clk_handle;
+ bool is_ecg = false;
+ int state = MDSS_DSI_CLK_OFF;
if (!ctrl) {
pr_err("%s: Invalid arg\n", __func__);
@@ -2113,6 +2117,18 @@ int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, void *clk_handle,
}
/*
+ * it should add and remove extra votes based on voting clients to avoid
+ * removal of legitimate vote from DSI client.
+ */
+ if (mctrl && (clk_handle == ctrl->dsi_clk_handle)) {
+ m_clk_handle = mctrl->dsi_clk_handle;
+ vote_cnt = &mctrl->m_dsi_vote_cnt;
+ } else if (mctrl) {
+ m_clk_handle = mctrl->mdp_clk_handle;
+ vote_cnt = &mctrl->m_mdp_vote_cnt;
+ }
+
+ /*
* When DSI is used in split mode, the link clock for master controller
* has to be turned on first before the link clock for slave can be
* turned on. In case the current controller is a slave, an ON vote is
@@ -2124,18 +2140,24 @@ int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, void *clk_handle,
__func__, ctrl->ndx, clk_type, clk_state,
__builtin_return_address(0), mctrl ? 1 : 0);
if (mctrl && (clk_type & MDSS_DSI_LINK_CLK)) {
- rc = mdss_dsi_clk_req_state(mctrl->dsi_clk_handle,
- MDSS_DSI_ALL_CLKS,
- MDSS_DSI_CLK_ON);
+ if (clk_state != MDSS_DSI_CLK_ON) {
+ /* preserve clk state; do not turn off forcefully */
+ is_ecg = is_dsi_clk_in_ecg_state(m_clk_handle);
+ if (is_ecg)
+ state = MDSS_DSI_CLK_EARLY_GATE;
+ }
+
+ rc = mdss_dsi_clk_req_state(m_clk_handle,
+ MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_ON, mctrl->ndx);
if (rc) {
pr_err("%s: failed to turn on mctrl clocks, rc=%d\n",
__func__, rc);
goto error;
}
- ctrl->m_vote_cnt++;
+ (*vote_cnt)++;
}
- rc = mdss_dsi_clk_req_state(clk_handle, clk_type, clk_state);
+ rc = mdss_dsi_clk_req_state(clk_handle, clk_type, clk_state, ctrl->ndx);
if (rc) {
pr_err("%s: failed set clk state, rc = %d\n", __func__, rc);
goto error;
@@ -2164,24 +2186,24 @@ int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, void *clk_handle,
* for ON, since the previous ECG state must have
* removed two votes to let clocks turn off.
*
- * To satisfy the above requirement, m_vote_cnt keeps track of
+ * To satisfy the above requirement, vote_cnt keeps track of
* the number of ON votes for master requested by slave. For
- * every OFF/ECG state request, Either 2 or m_vote_cnt number of
+ * every OFF/ECG state request, Either 2 or vote_cnt number of
* votes are removed depending on which is lower.
*/
- for (i = 0; (i < ctrl->m_vote_cnt && i < 2); i++) {
- rc = mdss_dsi_clk_req_state(mctrl->dsi_clk_handle,
- MDSS_DSI_ALL_CLKS,
- MDSS_DSI_CLK_OFF);
+ for (i = 0; (i < *vote_cnt && i < 2); i++) {
+ rc = mdss_dsi_clk_req_state(m_clk_handle,
+ MDSS_DSI_ALL_CLKS, state, mctrl->ndx);
if (rc) {
pr_err("%s: failed to set mctrl clk state, rc = %d\n",
__func__, rc);
goto error;
}
}
- ctrl->m_vote_cnt -= i;
- pr_debug("%s: ctrl=%d, m_vote_cnt=%d\n", __func__, ctrl->ndx,
- ctrl->m_vote_cnt);
+ (*vote_cnt) -= i;
+ pr_debug("%s: ctrl=%d, vote_cnt=%d dsi_vote_cnt=%d mdp_vote_cnt:%d\n",
+ __func__, ctrl->ndx, *vote_cnt, mctrl->m_dsi_vote_cnt,
+ mctrl->m_mdp_vote_cnt);
}
error:
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 2a5acbdc6327..fd2eb059b991 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -177,6 +177,14 @@ struct clk_rate_request {
* @set_flags: Set custom flags which deals with hardware specifics. Returns 0
* on success, -EEROR otherwise.
*
+ * @list_registers: Queries the hardware to get the current register contents.
+ * This callback is optional and required clocks could
+ * add this callback.
+ *
+ * @list_rate: Return the nth supported frequency for a given clock which is
+ * below rate_max on success and -ENXIO in case of no frequency
+ * table.
+ *
* The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow
* implementations to split any work between atomic (enable) and sleepable
* (prepare) contexts. If enabling a clock requires code that might sleep,
@@ -217,6 +225,10 @@ struct clk_ops {
void (*init)(struct clk_hw *hw);
int (*debug_init)(struct clk_hw *hw, struct dentry *dentry);
int (*set_flags)(struct clk_hw *hw, unsigned flags);
+ void (*list_registers)(struct seq_file *f,
+ struct clk_hw *hw);
+ long (*list_rate)(struct clk_hw *hw, unsigned n,
+ unsigned long rate_max);
};
/**
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 5110d4211866..ccb98b459c59 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -421,7 +421,11 @@ static inline void bpf_prog_unlock_ro(struct bpf_prog *fp)
}
#endif /* CONFIG_DEBUG_SET_MODULE_RONX */
-int sk_filter(struct sock *sk, struct sk_buff *skb);
+int sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb, unsigned int cap);
+static inline int sk_filter(struct sock *sk, struct sk_buff *skb)
+{
+ return sk_filter_trim_cap(sk, skb, 1);
+}
int bpf_prog_select_runtime(struct bpf_prog *fp);
void bpf_prog_free(struct bpf_prog *fp);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index c34a68ce901a..d33e10784b23 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -133,6 +133,7 @@ enum iommu_attr {
DOMAIN_ATTR_S1_BYPASS,
DOMAIN_ATTR_FAST,
DOMAIN_ATTR_PGTBL_INFO,
+ DOMAIN_ATTR_EARLY_MAP,
DOMAIN_ATTR_MAX,
};
diff --git a/include/linux/nfcinfo.h b/include/linux/nfcinfo.h
new file mode 100644
index 000000000000..595544f92a37
--- /dev/null
+++ b/include/linux/nfcinfo.h
@@ -0,0 +1,6 @@
+#ifndef _NFCINFO_H
+#define _NFCINFO_H
+
+#include <uapi/linux/nfc/nfcinfo.h>
+
+#endif
diff --git a/include/linux/qdsp6v2/apr_tal.h b/include/linux/qdsp6v2/apr_tal.h
index ee8b2f5a8b5b..c2c49dd748de 100644
--- a/include/linux/qdsp6v2/apr_tal.h
+++ b/include/linux/qdsp6v2/apr_tal.h
@@ -32,7 +32,7 @@
#if defined(CONFIG_MSM_QDSP6_APRV2_GLINK) || \
defined(CONFIG_MSM_QDSP6_APRV3_GLINK)
#define APR_MAX_BUF 512
-#define APR_NUM_OF_TX_BUF 20
+#define APR_NUM_OF_TX_BUF 30
#else
#define APR_MAX_BUF 8092
#endif
diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h
index 6848454c5447..5d0899df64ff 100644
--- a/include/linux/sched/sysctl.h
+++ b/include/linux/sched/sysctl.h
@@ -53,6 +53,8 @@ extern unsigned int sysctl_sched_spill_nr_run;
extern unsigned int sysctl_sched_spill_load_pct;
extern unsigned int sysctl_sched_upmigrate_pct;
extern unsigned int sysctl_sched_downmigrate_pct;
+extern unsigned int sysctl_sched_group_upmigrate_pct;
+extern unsigned int sysctl_sched_group_downmigrate_pct;
extern unsigned int sysctl_early_detection_duration;
extern unsigned int sysctl_sched_boost;
extern unsigned int sysctl_sched_small_wakee_task_load_pct;
diff --git a/include/linux/spmi.h b/include/linux/spmi.h
index 1396a255d2a2..319c52a298ef 100644
--- a/include/linux/spmi.h
+++ b/include/linux/spmi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 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,6 +171,19 @@ static inline void spmi_driver_unregister(struct spmi_driver *sdrv)
module_driver(__spmi_driver, spmi_driver_register, \
spmi_driver_unregister)
+#ifdef CONFIG_QCOM_SHOW_RESUME_IRQ
+extern int msm_show_resume_irq_mask;
+static inline bool spmi_show_resume_irq(void)
+{
+ return msm_show_resume_irq_mask;
+}
+#else
+static inline bool spmi_show_resume_irq(void)
+{
+ return false;
+}
+#endif
+
int spmi_register_read(struct spmi_device *sdev, u8 addr, u8 *buf);
int spmi_ext_register_read(struct spmi_device *sdev, u8 addr, u8 *buf,
size_t len);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 440248ba4123..7e6e4665212f 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -395,6 +395,15 @@ struct usb_bus {
struct mon_bus *mon_bus; /* non-null when associated */
int monitored; /* non-zero when monitored */
#endif
+ unsigned skip_resume:1; /* All USB devices are brought into full
+ * power state after system resume. It
+ * is desirable for some buses to keep
+ * their devices in suspend state even
+ * after system resume. The devices
+ * are resumed later when a remote
+ * wakeup is detected or an interface
+ * driver starts I/O.
+ */
};
struct usb_dev_state;
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 5ed36a59b08e..213601d620e0 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1171,6 +1171,7 @@ static inline void tcp_prequeue_init(struct tcp_sock *tp)
}
bool tcp_prequeue(struct sock *sk, struct sk_buff *skb);
+int tcp_filter(struct sock *sk, struct sk_buff *skb);
#undef STATE_TRACE
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 06b72b262395..e713641cc3ec 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -914,6 +914,34 @@ struct adm_cmd_connect_afe_port_v5 {
#define AFE_PORT_ID_SENARY_MI2S_RX 0x1018
/* ID of the senary MI2S Tx port. */
#define AFE_PORT_ID_SENARY_MI2S_TX 0x1019
+/* ID of the Internal 0 MI2S Rx port */
+#define AFE_PORT_ID_INT0_MI2S_RX 0x102E
+/* ID of the Internal 0 MI2S Tx port */
+#define AFE_PORT_ID_INT0_MI2S_TX 0x102F
+/* ID of the Internal 1 MI2S Rx port */
+#define AFE_PORT_ID_INT1_MI2S_RX 0x1030
+/* ID of the Internal 1 MI2S Tx port */
+#define AFE_PORT_ID_INT1_MI2S_TX 0x1031
+/* ID of the Internal 2 MI2S Rx port */
+#define AFE_PORT_ID_INT2_MI2S_RX 0x1032
+/* ID of the Internal 2 MI2S Tx port */
+#define AFE_PORT_ID_INT2_MI2S_TX 0x1033
+/* ID of the Internal 3 MI2S Rx port */
+#define AFE_PORT_ID_INT3_MI2S_RX 0x1034
+/* ID of the Internal 3 MI2S Tx port */
+#define AFE_PORT_ID_INT3_MI2S_TX 0x1035
+/* ID of the Internal 4 MI2S Rx port */
+#define AFE_PORT_ID_INT4_MI2S_RX 0x1036
+/* ID of the Internal 4 MI2S Tx port */
+#define AFE_PORT_ID_INT4_MI2S_TX 0x1037
+/* ID of the Internal 5 MI2S Rx port */
+#define AFE_PORT_ID_INT5_MI2S_RX 0x1038
+/* ID of the Internal 5 MI2S Tx port */
+#define AFE_PORT_ID_INT5_MI2S_TX 0x1039
+/* ID of the Internal 6 MI2S Rx port */
+#define AFE_PORT_ID_INT6_MI2S_RX 0x103A
+/* ID of the Internal 6 MI2S Tx port */
+#define AFE_PORT_ID_INT6_MI2S_TX 0x103B
#define AFE_PORT_ID_SPDIF_RX 0x5000
#define AFE_PORT_ID_RT_PROXY_PORT_001_RX 0x2000
#define AFE_PORT_ID_RT_PROXY_PORT_001_TX 0x2001
@@ -8858,6 +8886,20 @@ enum afe_lpass_clk_mode {
#define Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT 0x10D
/* Clock ID for SENARY I2S EBIT */
#define Q6AFE_LPASS_CLK_ID_SEN_MI2S_EBIT 0x10E
+/* Clock ID for INT0 I2S IBIT */
+#define Q6AFE_LPASS_CLK_ID_INT0_MI2S_IBIT 0x10F
+/* Clock ID for INT1 I2S IBIT */
+#define Q6AFE_LPASS_CLK_ID_INT1_MI2S_IBIT 0x110
+/* Clock ID for INT2 I2S IBIT */
+#define Q6AFE_LPASS_CLK_ID_INT2_MI2S_IBIT 0x111
+/* Clock ID for INT3 I2S IBIT */
+#define Q6AFE_LPASS_CLK_ID_INT3_MI2S_IBIT 0x112
+/* Clock ID for INT4 I2S IBIT */
+#define Q6AFE_LPASS_CLK_ID_INT4_MI2S_IBIT 0x113
+/* Clock ID for INT5 I2S IBIT */
+#define Q6AFE_LPASS_CLK_ID_INT5_MI2S_IBIT 0x114
+/* Clock ID for INT6 I2S IBIT */
+#define Q6AFE_LPASS_CLK_ID_INT6_MI2S_IBIT 0x115
/* Clock ID for Primary PCM IBIT */
#define Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT 0x200
@@ -8899,8 +8941,19 @@ enum afe_lpass_clk_mode {
#define Q6AFE_LPASS_CLK_ID_MCLK_2 0x301
/* Clock ID for MCLK3 */
#define Q6AFE_LPASS_CLK_ID_MCLK_3 0x302
+/* Clock ID for MCLK4 */
+#define Q6AFE_LPASS_CLK_ID_MCLK_4 0x304
/* Clock ID for Internal Digital Codec Core */
#define Q6AFE_LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE 0x303
+/* Clock ID for INT MCLK0 */
+#define Q6AFE_LPASS_CLK_ID_INT_MCLK_0 0x305
+/* Clock ID for INT MCLK1 */
+#define Q6AFE_LPASS_CLK_ID_INT_MCLK_1 0x306
+/*
+ * Clock ID for soundwire NPL.
+ * This is the clock to be used to enable NPL clock for internal Soundwire.
+ */
+#define AFE_CLOCK_SET_CLOCK_ID_SWR_NPL_CLK 0x307
/* Clock ID for AHB HDMI input */
#define Q6AFE_LPASS_CLK_ID_AHB_HDMI_INPUT 0x400
diff --git a/include/sound/msm-dai-q6-v2.h b/include/sound/msm-dai-q6-v2.h
index c3c65a02a817..b1d76bf73f51 100644
--- a/include/sound/msm-dai-q6-v2.h
+++ b/include/sound/msm-dai-q6-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 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
@@ -28,8 +28,15 @@
#define MSM_SEC_MI2S_SD1 4
#define MSM_QUIN_MI2S 5
#define MSM_SENARY_MI2S 6
+#define MSM_INT0_MI2S 7
+#define MSM_INT1_MI2S 8
+#define MSM_INT2_MI2S 9
+#define MSM_INT3_MI2S 10
+#define MSM_INT4_MI2S 11
+#define MSM_INT5_MI2S 12
+#define MSM_INT6_MI2S 13
#define MSM_MI2S_MIN MSM_PRIM_MI2S
-#define MSM_MI2S_MAX MSM_SENARY_MI2S
+#define MSM_MI2S_MAX MSM_INT6_MI2S
struct msm_dai_auxpcm_config {
u16 mode;
diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h
index 31f7c02b54b3..e0da428fa52f 100644
--- a/include/sound/q6afe-v2.h
+++ b/include/sound/q6afe-v2.h
@@ -183,10 +183,26 @@ enum {
IDX_AFE_PORT_ID_USB_TX,
/* IDX 124 */
IDX_DISPLAY_PORT_RX,
+ /* IDX 125-> 128 */
IDX_AFE_PORT_ID_TERTIARY_PCM_RX,
IDX_AFE_PORT_ID_TERTIARY_PCM_TX,
IDX_AFE_PORT_ID_QUATERNARY_PCM_RX,
IDX_AFE_PORT_ID_QUATERNARY_PCM_TX,
+ /* IDX 129-> 142 */
+ IDX_AFE_PORT_ID_INT0_MI2S_RX,
+ IDX_AFE_PORT_ID_INT0_MI2S_TX,
+ IDX_AFE_PORT_ID_INT1_MI2S_RX,
+ IDX_AFE_PORT_ID_INT1_MI2S_TX,
+ IDX_AFE_PORT_ID_INT2_MI2S_RX,
+ IDX_AFE_PORT_ID_INT2_MI2S_TX,
+ IDX_AFE_PORT_ID_INT3_MI2S_RX,
+ IDX_AFE_PORT_ID_INT3_MI2S_TX,
+ IDX_AFE_PORT_ID_INT4_MI2S_RX,
+ IDX_AFE_PORT_ID_INT4_MI2S_TX,
+ IDX_AFE_PORT_ID_INT5_MI2S_RX,
+ IDX_AFE_PORT_ID_INT5_MI2S_TX,
+ IDX_AFE_PORT_ID_INT6_MI2S_RX,
+ IDX_AFE_PORT_ID_INT6_MI2S_TX,
AFE_MAX_PORTS
};
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index 7778ff3947de..72bbed9ad5db 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -133,6 +133,7 @@ TRACE_EVENT(sched_task_load,
__field( u32, flags )
__field( int, best_cpu )
__field( u64, latency )
+ __field( int, grp_id )
),
TP_fast_assign(
@@ -148,12 +149,13 @@ TRACE_EVENT(sched_task_load,
__entry->latency = p->state == TASK_WAKING ?
sched_ktime_clock() -
p->ravg.mark_start : 0;
+ __entry->grp_id = p->grp ? p->grp->id : 0;
),
- TP_printk("%d (%s): demand=%u boost=%d reason=%d sync=%d need_idle=%d flags=%x best_cpu=%d latency=%llu",
+ TP_printk("%d (%s): demand=%u boost=%d reason=%d sync=%d need_idle=%d flags=%x grp=%d best_cpu=%d latency=%llu",
__entry->pid, __entry->comm, __entry->demand,
__entry->boost, __entry->reason, __entry->sync,
- __entry->need_idle, __entry->flags,
+ __entry->need_idle, __entry->flags, __entry->grp_id,
__entry->best_cpu, __entry->latency)
);
@@ -164,9 +166,12 @@ TRACE_EVENT(sched_set_preferred_cluster,
TP_ARGS(grp, total_demand),
TP_STRUCT__entry(
- __field( int, id )
- __field( u64, demand )
- __field( int, cluster_first_cpu )
+ __field( int, id )
+ __field( u64, demand )
+ __field( int, cluster_first_cpu )
+ __array( char, comm, TASK_COMM_LEN )
+ __field( pid_t, pid )
+ __field(unsigned int, task_demand )
),
TP_fast_assign(
@@ -245,19 +250,19 @@ DEFINE_EVENT(sched_cpu_load, sched_cpu_load_cgroup,
TRACE_EVENT(sched_set_boost,
- TP_PROTO(int ref_count),
+ TP_PROTO(int type),
- TP_ARGS(ref_count),
+ TP_ARGS(type),
TP_STRUCT__entry(
- __field(unsigned int, ref_count )
+ __field(int, type )
),
TP_fast_assign(
- __entry->ref_count = ref_count;
+ __entry->type = type;
),
- TP_printk("ref_count=%d", __entry->ref_count)
+ TP_printk("type %d", __entry->type)
);
#if defined(CREATE_TRACE_POINTS) && defined(CONFIG_SCHED_HMP)
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index d6ff882ad6a7..14bd1e806ad7 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -23,6 +23,7 @@ header-y += netfilter_ipv6/
header-y += usb/
header-y += wimax/
header-y += mfd/
+header-y += nfc/
genhdr-y += version.h
diff --git a/include/uapi/linux/nfc/Kbuild b/include/uapi/linux/nfc/Kbuild
new file mode 100644
index 000000000000..90710153e462
--- /dev/null
+++ b/include/uapi/linux/nfc/Kbuild
@@ -0,0 +1,2 @@
+#UAPI export list
+header-y += nfcinfo.h
diff --git a/include/uapi/linux/nfc/nfcinfo.h b/include/uapi/linux/nfc/nfcinfo.h
new file mode 100644
index 000000000000..df178e2bbae6
--- /dev/null
+++ b/include/uapi/linux/nfc/nfcinfo.h
@@ -0,0 +1,21 @@
+#ifndef _UAPI_NFCINFO_H_
+#define _UAPI_NFCINFO_H_
+
+#include <linux/ioctl.h>
+
+#define NFCC_MAGIC 0xE9
+#define NFCC_GET_INFO _IOW(NFCC_MAGIC, 0x09, unsigned int)
+
+struct nqx_devinfo {
+ unsigned char chip_type;
+ unsigned char rom_version;
+ unsigned char fw_major;
+ unsigned char fw_minor;
+};
+
+union nqx_uinfo {
+ unsigned int i;
+ struct nqx_devinfo info;
+};
+
+#endif
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 643c68f4c449..8fdf57504ab6 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -1199,6 +1199,15 @@ enum v4l2_cid_mpeg_vidc_video_full_range {
#define V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS \
(V4L2_CID_MPEG_MSM_VIDC_BASE + 97)
+#define V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 98)
+enum v4l2_mpeg_vidc_video_venc_iframesize_type {
+ V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_DEFAULT,
+ V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_MEDIUM,
+ V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_HUGE,
+ V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED,
+};
+
/* Camera class control IDs */
#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900)
diff --git a/include/uapi/media/msm_sde_rotator.h b/include/uapi/media/msm_sde_rotator.h
index 12976e3f14d7..4487edf0c854 100644
--- a/include/uapi/media/msm_sde_rotator.h
+++ b/include/uapi/media/msm_sde_rotator.h
@@ -86,10 +86,4 @@ struct msm_sde_rotator_fence {
/* SDE Rotator private control ID's */
#define V4L2_CID_SDE_ROTATOR_SECURE (V4L2_CID_USER_BASE + 0x1000)
-/*
- * This control Id indicates this context is associated with the
- * secure camera
- */
-#define V4L2_CID_SDE_ROTATOR_SECURE_CAMERA (V4L2_CID_USER_BASE + 0x2000)
-
#endif /* __UAPI_MSM_SDE_ROTATOR_H__ */
diff --git a/include/uapi/media/msmb_ispif.h b/include/uapi/media/msmb_ispif.h
index 7f4deaf12683..3720056aa28d 100644
--- a/include/uapi/media/msmb_ispif.h
+++ b/include/uapi/media/msmb_ispif.h
@@ -28,6 +28,7 @@ enum msm_ispif_intftype {
};
#define MAX_PARAM_ENTRIES (INTF_MAX * 2)
#define MAX_CID_CH 8
+#define MAX_CID_CH_PARAM_ENTRY 3
#define PIX0_MASK (1 << PIX0)
#define PIX1_MASK (1 << PIX1)
@@ -94,7 +95,7 @@ struct msm_ispif_params_entry {
enum msm_ispif_vfe_intf vfe_intf;
enum msm_ispif_intftype intftype;
int num_cids;
- enum msm_ispif_cid cids[3];
+ enum msm_ispif_cid cids[MAX_CID_CH_PARAM_ENTRY];
enum msm_ispif_csid csid;
int crop_enable;
uint16_t crop_start_pixel;
diff --git a/kernel/Documentation/firmware_updater/request_firmware.txt b/kernel/Documentation/firmware_updater/request_firmware.txt
deleted file mode 100644
index 317f04ac5684..000000000000
--- a/kernel/Documentation/firmware_updater/request_firmware.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Firmware Update Function
-========================
-
-Call export function "synaptics_fw_updater" in rmi_fw_update.c to start
-firmware updating process in the driver.
-
-The RMI4 driver uses the kernel's request_firmware() feature to obtain
-firmware for the touch sensor. The firmware is expected to live in
-the file firmware/<firmware_name>.img.ihex.
-
-To prepare Synaptics provided .img file for reflashing, convert it to .ihex
-format using the following command:
-
- objcopy -I binary -O ihex <firmware_name>.img firmware/<firmware_name>.img.ihex
-
-Then make sure to add the image file name to the
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_FW_UPDATE entry in firmware/Makefile.
-If you don't do this, the image file won't be included, and
-the firmware loader class will delay for 60 seconds waiting for a non-existent
-userspace response to the firmware load request.
-
-Firmware updates for multichip solutions (aka LTS) are not supported.
diff --git a/kernel/Documentation/firmware_updater/synaptics_fw_updater b/kernel/Documentation/firmware_updater/synaptics_fw_updater
deleted file mode 100644
index b0c1b4d9e770..000000000000
--- a/kernel/Documentation/firmware_updater/synaptics_fw_updater
+++ /dev/null
Binary files differ
diff --git a/kernel/Documentation/firmware_updater/synaptics_fw_updater.c b/kernel/Documentation/firmware_updater/synaptics_fw_updater.c
deleted file mode 100644
index 7409dd424109..000000000000
--- a/kernel/Documentation/firmware_updater/synaptics_fw_updater.c
+++ /dev/null
@@ -1,753 +0,0 @@
-/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- *
- * Copyright © 2011, 2012 Synaptics Incorporated. All rights reserved.
- *
- * The information in this file is confidential under the terms
- * of a non-disclosure agreement with Synaptics and is provided
- * AS IS without warranties or guarantees of any kind.
- *
- * The information in this file shall remain the exclusive property
- * of Synaptics and may be the subject of Synaptics patents, in
- * whole or part. Synaptics intellectual property rights in the
- * information in this file are not expressly or implicitly licensed
- * or otherwise transferred to you as a result of such information
- * being made available to you.
- *
- * File: synaptics_fw_updater.c
- *
- * Description: command line reflash implimentation using command
- * line args. This file should not be OS dependant and should build and
- * run under any Linux based OS that utilizes the Synaptice rmi driver
- * built into the kernel (kernel/drivers/input/rmi4).
- *
- * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-#define DEFAULT_SENSOR "/sys/class/input/input1"
-
-#define MAX_STRING_LEN 256
-#define MAX_INT_LEN 33
-
-#define DATA_FILENAME "data"
-#define IMAGESIZE_FILENAME "imagesize"
-#define DOREFLASH_FILENAME "doreflash"
-#define CONFIGAREA_FILENAME "configarea"
-#define READCONFIG_FILENAME "readconfig"
-#define WRITECONFIG_FILENAME "writeconfig"
-#define BLOCKSIZE_FILENAME "blocksize"
-#define IMAGEBLOCKCOUNT_FILENAME "fwblockcount"
-#define CONFIGBLOCKCOUNT_FILENAME "configblockcount"
-#define PMCONFIGBLOCKCOUNT_FILENAME "permconfigblockcount"
-#define BUILDID_FILENAME "buildid"
-#define FLASHPROG_FILENAME "flashprog"
-
-#define UI_CONFIG_AREA 0
-#define PERM_CONFIG_AREA 1
-#define BL_CONFIG_AREA 2
-#define DISP_CONFIG_AREA 3
-
-#define IMAGE_FILE_CHECKSUM_SIZE 4
-
-unsigned char *firmware = NULL;
-int fileSize;
-int firmwareBlockSize;
-int firmwareBlockCount;
-int firmwareImgSize;
-int configBlockSize;
-int configBlockCount;
-int configImgSize;
-int totalBlockCount;
-int readConfig = 0;
-int writeConfig = 0;
-int uiConfig = 0;
-int pmConfig = 0;
-int blConfig = 0;
-int dpConfig = 0;
-int force = 0;
-int verbose = 0;
-
-char mySensor[MAX_STRING_LEN];
-char imageFileName[MAX_STRING_LEN];
-
-static void usage(char *name)
-{
- printf("Usage: %s [-b {image_file}] [-d {sysfs_entry}] [-r] [-ui] [-pm] [-bl] [-dp] [-f] [-v]\n", name);
- printf("\t[-b {image_file}] - Name of image file\n");
- printf("\t[-d {sysfs_entry}] - Path to sysfs entry of sensor\n");
- printf("\t[-r] - Read config area\n");
- printf("\t[-ui] - UI config area\n");
- printf("\t[-pm] - Permanent config area\n");
- printf("\t[-bl] - BL config area\n");
- printf("\t[-dp] - Display config area\n");
- printf("\t[-f] - Force reflash\n");
- printf("\t[-v] - Verbose output\n");
-
- return;
-}
-
-static void TimeSubtract(struct timeval *result, struct timeval *x, struct timeval *y)
-{
- if (x->tv_usec < y->tv_usec) {
- result->tv_sec = x->tv_sec - y->tv_sec - 1;
- result->tv_usec = y->tv_usec - x->tv_usec;
- } else {
- result->tv_sec = x->tv_sec - y->tv_sec;
- result->tv_usec = x->tv_usec - y->tv_usec;
- }
-
- return;
-}
-
-static int CheckSysfsEntry(char *sensorName)
-{
- int retval;
- struct stat st;
-
- retval = stat(sensorName, &st);
- if (retval)
- printf("ERROR: sensor sysfs entry %s not found\n", sensorName);
-
- return retval;
-}
-
-static void WriteBinData(char *fname, unsigned char *buf, int len)
-{
- int numBytesWritten;
- FILE *fp;
-
- fp = fopen(fname, "wb");
- if (!fp) {
- printf("ERROR: failed to open %s for writing data\n", fname);
- exit(EIO);
- }
-
- numBytesWritten = fwrite(buf, 1, len, fp);
-
- if (numBytesWritten != len) {
- printf("ERROR: failed to write all data to bin file\n");
- fclose(fp);
- exit(EIO);
- }
-
- fclose(fp);
-
- return;
-}
-
-static void ReadBinData(char *fname, unsigned char *buf, int len)
-{
- int numBytesRead;
- FILE *fp;
-
- fp = fopen(fname, "rb");
- if (!fp) {
- printf("ERROR: failed to open %s for reading data\n", fname);
- exit(EIO);
- }
-
- numBytesRead = fread(buf, 1, len, fp);
-
- if (numBytesRead != len) {
- printf("ERROR: failed to read all data from bin file\n");
- fclose(fp);
- exit(EIO);
- }
-
- fclose(fp);
-
- return;
-}
-
-static void WriteValueToFp(FILE *fp, unsigned int value)
-{
- int numBytesWritten;
- char buf[MAX_INT_LEN];
-
- snprintf(buf, MAX_INT_LEN, "%u", value);
-
- fseek(fp, 0, 0);
-
- numBytesWritten = fwrite(buf, 1, strlen(buf) + 1, fp);
- if (numBytesWritten != ((int)(strlen(buf) + 1))) {
- printf("ERROR: failed to write value to file pointer\n");
- fclose(fp);
- exit(EIO);
- }
-
- return;
-}
-
-static void WriteValueToSysfsFile(char *fname, unsigned int value)
-{
- FILE *fp;
-
- fp = fopen(fname, "w");
- if (!fp) {
- printf("ERROR: failed to open %s for writing value\n", fname);
- exit(EIO);
- }
-
- WriteValueToFp(fp, value);
-
- fclose(fp);
-
- return;
-}
-
-static void ReadValueFromFp(FILE *fp, unsigned int *value)
-{
- int retVal;
- char buf[MAX_INT_LEN];
-
- fseek(fp, 0, 0);
-
- retVal = fread(buf, 1, sizeof(buf), fp);
- if (retVal == -1) {
- printf("ERROR: failed to read value from file pointer\n");
- exit(EIO);
- }
-
- *value = strtoul(buf, NULL, 0);
-
- return;
-}
-
-static void ReadValueFromSysfsFile(char *fname, unsigned int *value)
-{
- FILE *fp;
-
- fp = fopen(fname, "r");
- if (!fp) {
- printf("ERROR: failed to open %s for reading value\n", fname);
- exit(EIO);
- }
-
- ReadValueFromFp(fp, value);
-
- fclose(fp);
-
- return;
-}
-
-static void WriteBlockData(char *buf, int len)
-{
- char tmpfname[MAX_STRING_LEN];
-
- snprintf(tmpfname, MAX_STRING_LEN, "%s/%s", mySensor, DATA_FILENAME);
-
- WriteBinData(tmpfname, (unsigned char *)buf, len);
-
- return;
-}
-
-static void ReadBlockData(char *buf, int len)
-{
- char tmpfname[MAX_STRING_LEN];
-
- snprintf(tmpfname, MAX_STRING_LEN, "%s/%s", mySensor, DATA_FILENAME);
-
- ReadBinData(tmpfname, (unsigned char *)buf, len);
-
- return;
-}
-
-static void SetImageSize(int value)
-{
- char tmpfname[MAX_STRING_LEN];
-
- snprintf(tmpfname, MAX_STRING_LEN, "%s/%s", mySensor, IMAGESIZE_FILENAME);
-
- WriteValueToSysfsFile(tmpfname, value);
-
- return;
-}
-
-static void StartReflash(int value)
-{
- char tmpfname[MAX_STRING_LEN];
-
- snprintf(tmpfname, MAX_STRING_LEN, "%s/%s", mySensor, DOREFLASH_FILENAME);
-
- WriteValueToSysfsFile(tmpfname, value);
-
- return;
-}
-
-static void SetConfigArea(int value)
-{
- char tmpfname[MAX_STRING_LEN];
-
- snprintf(tmpfname, MAX_STRING_LEN, "%s/%s", mySensor, CONFIGAREA_FILENAME);
-
- WriteValueToSysfsFile(tmpfname, value);
-
- return;
-}
-
-static void StartWriteConfig(int value)
-{
- char tmpfname[MAX_STRING_LEN];
-
- snprintf(tmpfname, MAX_STRING_LEN, "%s/%s", mySensor, WRITECONFIG_FILENAME);
-
- WriteValueToSysfsFile(tmpfname, value);
-
- return;
-}
-
-static void StartReadConfig(int value)
-{
- char tmpfname[MAX_STRING_LEN];
-
- snprintf(tmpfname, MAX_STRING_LEN, "%s/%s", mySensor, READCONFIG_FILENAME);
-
- WriteValueToSysfsFile(tmpfname, value);
-
- return;
-}
-
-static int ReadBlockSize(void)
-{
- unsigned int blockSize;
- char tmpfname[MAX_STRING_LEN];
-
- snprintf(tmpfname, MAX_STRING_LEN, "%s/%s", mySensor, BLOCKSIZE_FILENAME);
-
- ReadValueFromSysfsFile(tmpfname, &blockSize);
-
- return blockSize;
-}
-
-static int ReadFirmwareBlockCount(void)
-{
- unsigned int imageBlockCount;
- char tmpfname[MAX_STRING_LEN];
-
- snprintf(tmpfname, MAX_STRING_LEN, "%s/%s", mySensor, IMAGEBLOCKCOUNT_FILENAME);
-
- ReadValueFromSysfsFile(tmpfname, &imageBlockCount);
-
- return imageBlockCount;
-}
-
-static int ReadConfigBlockCount(void)
-{
- unsigned int configBlockCount;
- char tmpfname[MAX_STRING_LEN];
-
- snprintf(tmpfname, MAX_STRING_LEN, "%s/%s", mySensor, CONFIGBLOCKCOUNT_FILENAME);
-
- ReadValueFromSysfsFile(tmpfname, &configBlockCount);
-
- return configBlockCount;
-}
-
-static int ReadPmConfigBlockCount(void)
-{
- unsigned int configBlockCount;
- char tmpfname[MAX_STRING_LEN];
-
- snprintf(tmpfname, MAX_STRING_LEN, "%s/%s", mySensor, PMCONFIGBLOCKCOUNT_FILENAME);
-
- ReadValueFromSysfsFile(tmpfname, &configBlockCount);
-
- return configBlockCount;
-}
-
-static int ReadBuildID(void)
-{
- unsigned int buildID;
- char tmpfname[MAX_STRING_LEN];
-
- snprintf(tmpfname, MAX_STRING_LEN, "%s/%s", mySensor, BUILDID_FILENAME);
-
- ReadValueFromSysfsFile(tmpfname, &buildID);
-
- return buildID;
-}
-
-static int ReadFlashProg(void)
-{
- unsigned int flashProg;
- char tmpfname[MAX_STRING_LEN];
-
- snprintf(tmpfname, MAX_STRING_LEN, "%s/%s", mySensor, FLASHPROG_FILENAME);
-
- ReadValueFromSysfsFile(tmpfname, &flashProg);
-
- return flashProg;
-}
-
-static void ReadFirmwareInfo(void)
-{
- firmwareBlockSize = ReadBlockSize();
- firmwareBlockCount = ReadFirmwareBlockCount();
- firmwareImgSize = firmwareBlockCount * firmwareBlockSize;
-
- return;
-}
-
-static void ReadConfigInfo(void)
-{
- configBlockSize = ReadBlockSize();
- configBlockCount = ReadConfigBlockCount();
- configImgSize = configBlockSize * configBlockCount;
-
- return;
-}
-
-static void CalculateChecksum(unsigned short *data, unsigned short len, unsigned long *result)
-{
- unsigned long temp;
- unsigned long sum1 = 0xffff;
- unsigned long sum2 = 0xffff;
-
- *result = 0xffffffff;
-
- while (len--) {
- temp = *data;
- sum1 += temp;
- sum2 += sum1;
- sum1 = (sum1 & 0xffff) + (sum1 >> 16);
- sum2 = (sum2 & 0xffff) + (sum2 >> 16);
- data++;
- }
-
- *result = sum2 << 16 | sum1;
-
- return;
-}
-
-static int CompareChecksum(void)
-{
- unsigned long headerChecksum;
- unsigned long computedChecksum;
-
- headerChecksum = (unsigned long)firmware[0] +
- (unsigned long)firmware[1] * 0x100 +
- (unsigned long)firmware[2] * 0x10000 +
- (unsigned long)firmware[3] * 0x1000000;
-
- CalculateChecksum((unsigned short *)&firmware[IMAGE_FILE_CHECKSUM_SIZE],
- ((fileSize - IMAGE_FILE_CHECKSUM_SIZE) / 2), &computedChecksum);
-
- if (verbose) {
- printf("Checksum in image file header = 0x%08x\n", (unsigned int)headerChecksum);
- printf("Checksum computed from image file = 0x%08x\n", (unsigned int)computedChecksum);
- }
-
- if (headerChecksum == computedChecksum)
- return 1;
- else
- return 0;
-}
-
-static int ProceedWithReflash(void)
-{
- int index = 0;
- int deviceBuildID;
- int imageBuildID;
- char imagePR[MAX_STRING_LEN];
- char *strptr;
-
- if (force) {
- printf("Force reflash...\n");
- return 1;
- }
-
- if (ReadFlashProg()) {
- printf("Force reflash (device in flash prog mode)...\n");
- return 1;
- }
-
- strptr = strstr(imageFileName, "PR");
- if (!strptr) {
- printf("No valid PR number (PRxxxxxxx) found in image file name...\n");
- return 0;
- }
-
- strptr += 2;
- while (strptr[index] >= '0' && strptr[index] <= '9') {
- imagePR[index] = strptr[index];
- index++;
- }
- imagePR[index] = 0;
-
- imageBuildID = strtoul(imagePR, NULL, 0);
- deviceBuildID = ReadBuildID();
- printf("Image file PR = %d\n", imageBuildID);
- printf("Device PR = %d\n", deviceBuildID);
-
- if (imageBuildID > deviceBuildID) {
- printf("Proceed with reflash...\n");
- return 1;
- } else {
- printf("No need to do reflash...\n");
- return 0;
- }
-}
-
-static void DoReadConfig(void)
-{
- int ii;
- int jj;
- int index = 0;
- int configSize;
- int blockCount;
- unsigned char *buffer;
-
- if (uiConfig) {
- SetConfigArea(UI_CONFIG_AREA);
- StartReadConfig(1);
- blockCount = configBlockCount;
- configSize = configImgSize;
- buffer = malloc(configSize);
- if (!buffer)
- exit(ENOMEM);
- ReadBlockData((char *)&buffer[0], configSize);
- } else if (pmConfig) {
- SetConfigArea(PERM_CONFIG_AREA);
- StartReadConfig(1);
- blockCount = ReadPmConfigBlockCount();
- configSize = configBlockSize * blockCount;
- buffer = malloc(configSize);
- if (!buffer)
- exit(ENOMEM);
- ReadBlockData((char *)&buffer[0], configSize);
- } else {
- return;
- }
-
- for (ii = 0; ii < blockCount; ii++) {
- for (jj = 0; jj < configBlockSize; jj++) {
- printf("0x%02x ", buffer[index]);
- index++;
- }
- printf("\n");
- }
-
- free(buffer);
-
- return;
-}
-
-static void DoWriteConfig(void)
-{
- printf("Starting config programming...\n");
-
- if (uiConfig)
- SetConfigArea(UI_CONFIG_AREA);
- else if (pmConfig)
- SetConfigArea(PERM_CONFIG_AREA);
- else if (blConfig)
- SetConfigArea(BL_CONFIG_AREA);
- else if (dpConfig)
- SetConfigArea(DISP_CONFIG_AREA);
- else
- return;
-
- SetImageSize(fileSize);
- WriteBlockData((char *)&firmware[0], fileSize);
- StartWriteConfig(1);
-
- printf("Config programming completed...\n");
-
- return;
-}
-
-static void DoReflash(void)
-{
- if (verbose)
- printf("Blocks: %d (firmware: %d, config: %d)\n", totalBlockCount, firmwareBlockCount, configBlockCount);
-
- if (!ProceedWithReflash())
- return;
-
- printf("Starting reflash...\n");
-
- SetImageSize(fileSize);
- WriteBlockData((char *)&firmware[0], fileSize);
- StartReflash(1);
-
- printf("Reflash completed...\n");
-
- return;
-}
-
-static int InitFirmwareImage(void)
-{
- int numBytesRead;
- FILE *fp;
-
- if (!readConfig) {
- fp = fopen(imageFileName, "rb");
-
- if (!fp) {
- printf("ERROR: image file %s not found\n", imageFileName);
- exit(ENODEV);
- }
-
- fseek(fp, 0L, SEEK_END);
- fileSize = ftell(fp);
- if (fileSize == -1) {
- printf("ERROR: failed to determine size of %s\n", imageFileName);
- exit(EIO);
- }
-
- fseek(fp, 0L, SEEK_SET);
-
- firmware = malloc(fileSize + 1);
- if (!firmware) {
- exit(ENOMEM);
- } else {
- numBytesRead = fread(firmware, 1, fileSize, fp);
- if (numBytesRead != fileSize) {
- printf("ERROR: failed to read entire content of image file\n");
- exit(EIO);
- }
- }
-
- fclose(fp);
-
- if (!(pmConfig || blConfig || dpConfig)) {
- if (!CompareChecksum()) {
- printf("ERROR: failed to validate checksum of image file\n");
- exit(EINVAL);
- }
- }
- }
-
- return 0;
-}
-
-int main(int argc, char* argv[])
-{
- int retVal;
- int this_arg = 1;
- struct stat st;
- struct timeval start_time;
- struct timeval end_time;
- struct timeval elapsed_time;
-
- if (argc == 1) {
- usage(argv[0]);
- exit(EINVAL);
- }
-
- while (this_arg < argc) {
- if (!strcmp((const char *)argv[this_arg], "-b")) {
- /* Image file */
- FILE *file;
-
- this_arg++;
- if (this_arg >= argc) {
- printf("ERROR: image file missing\n");
- exit(EINVAL);
- }
-
- /* check for presence of image file */
- file = fopen(argv[this_arg], "rb");
- if (file == 0) {
- printf("ERROR: image file %s not found\n", argv[this_arg]);
- exit(EINVAL);
- }
- fclose(file);
-
- strncpy(imageFileName, argv[this_arg], MAX_STRING_LEN);
- } else if (!strcmp((const char *)argv[this_arg], "-d")) {
- /* path to sensor sysfs entry */
- this_arg++;
-
- if (stat(argv[this_arg], &st) == 0) {
- strncpy(mySensor, argv[this_arg], MAX_STRING_LEN);
- } else {
- printf("ERROR: sensor sysfs entry %s not found\n", argv[this_arg]);
- exit(EINVAL);
- }
- } else if (!strcmp((const char *)argv[this_arg], "-r")) {
- readConfig = 1;
- } else if (!strcmp((const char *)argv[this_arg], "-ui")) {
- uiConfig = 1;
- } else if (!strcmp((const char *)argv[this_arg], "-pm")) {
- pmConfig = 1;
- } else if (!strcmp((const char *)argv[this_arg], "-bl")) {
- blConfig = 1;
- } else if (!strcmp((const char *)argv[this_arg], "-dp")) {
- dpConfig = 1;
- } else if (!strcmp((const char *)argv[this_arg], "-f")) {
- force = 1;
- } else if (!strcmp((const char *)argv[this_arg], "-v")) {
- verbose = 1;
- } else {
- usage(argv[0]);
- printf("ERROR: invalid parameter %s supplied\n", argv[this_arg]);
- exit(EINVAL);
- }
- this_arg++;
- }
-
- if ((uiConfig + pmConfig + blConfig + dpConfig) > 1) {
- printf("ERROR: too many parameters\n");
- exit(EINVAL);
- }
-
- if (uiConfig || pmConfig || blConfig || dpConfig)
- writeConfig = 1;
-
- if (!readConfig && !strlen(imageFileName)) {
- printf("ERROR: no image file specified\n");
- exit(EINVAL);
- }
-
- if (!strlen(mySensor))
- strncpy(mySensor, DEFAULT_SENSOR, MAX_STRING_LEN);
-
- if (CheckSysfsEntry(mySensor))
- exit(ENODEV);
-
- InitFirmwareImage();
-
- ReadFirmwareInfo();
- ReadConfigInfo();
- totalBlockCount = configBlockCount + firmwareBlockCount;
-
- retVal = gettimeofday(&start_time, NULL);
- if (retVal)
- printf("WARNING: failed to get start time\n");
-
- if (verbose) {
- if (!readConfig)
- printf("Image file: %s\n", imageFileName);
- printf("Sensor sysfs entry: %s\n", mySensor);
- }
-
- if (readConfig)
- DoReadConfig();
- else if (writeConfig)
- DoWriteConfig();
- else
- DoReflash();
-
- retVal = gettimeofday(&end_time, NULL);
- if (retVal)
- printf("WARNING: failed to get end time\n");
-
- TimeSubtract(&elapsed_time, &end_time, &start_time);
-
- if (verbose) {
- printf("Elapsed time = %ld.%06ld seconds\n",
- (long)elapsed_time.tv_sec,
- (long)elapsed_time.tv_usec);
- }
-
- return 0;
-}
diff --git a/kernel/Documentation/firmware_updater/synaptics_fw_updater_readme.txt b/kernel/Documentation/firmware_updater/synaptics_fw_updater_readme.txt
deleted file mode 100644
index 66f71922995a..000000000000
--- a/kernel/Documentation/firmware_updater/synaptics_fw_updater_readme.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-Use ADB (Android Debug Bridge) to do command-line reflash
-- Power on device.
-- Connect device to host via USB.
-- Open command prompt on host and go to directory where adb, synaptics_fw_updater, and FW image (e.g. PR1234567.img) reside.
-- Run "adb devices" to ensure connection with device.
-- Run "adb root" to have root privileges.
-- Run "adb push synaptics_fw_updater /data" to copy synaptics_fw_updater to /data directory on device.
-- Run "adb push firmware.img /data" to copy firmware.img to /data directory on device.
-- Run "adb shell chmod 777 /data/synaptics_fw_updater" to make synaptics_fw_updater executable.
-- Run "adb shell /data/synaptics_fw_updater -b /data/PR1234567.img -f -v" to start reflash process.
-
-Parameters
-[-b {image_file}] - Name of image file
-[-d {sysfs_entry}] - Path to sysfs entry of sensor
-[-r] - Read config area
-[-ui] - UI config area
-[-pm] - Permanent config area
-[-bl] - BL config area
-[-dp] - Display config area
-[-f] - Force reflash
-[-v] - Verbose output
-
-Procedures for checking whether to proceed with reflash
-- If [-f] flag is set, proceed with reflash
-- If device is in flash prog (bootloader) mode, proceed with reflash
-- If PR number contained in name of new FW image is greater than PR number of FW on device, proceed with reflash.
-- Otherwise, no reflash is performed
-
-Usage examples
-- Perform reflash using PR1234567.img regardless of PR number of FW on device
- synaptics_fw_updater -b PR1234567.img -f
-- Perform reflash using PR1234567.img only if 1234567 is greater than PR number of FW on device.
- synaptics_fw_updater -b PR1234567.img
-- Write UI config area from PR1234567.img (parsing UI config area from firmware image file)
- synaptics_fw_updater -b PR1234567.img -ui
-- Write permanent config area from pmconfig.img (binary file containing permanent config data)
- synaptics_fw_updater -b pmconfig.img -pm
-- Read UI config area
- synaptics_fw_updater -r -ui
-- Read permanent config area
- synaptics_fw_updater -r -pm \ No newline at end of file
diff --git a/kernel/arch/arm/configs/omap3_beagle_android_defconfig b/kernel/arch/arm/configs/omap3_beagle_android_defconfig
deleted file mode 100644
index 4fc62c4fa440..000000000000
--- a/kernel/arch/arm/configs/omap3_beagle_android_defconfig
+++ /dev/null
@@ -1,2419 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux/arm 2.6.37 Kernel Configuration
-# Mon Apr 16 13:58:06 2012
-#
-CONFIG_ARM=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_GENERIC_GPIO=y
-# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_HAVE_PROC_CPU=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_ARCH_HAS_CPUFREQ=y
-CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_VECTORS_BASE=0xffff0000
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-CONFIG_CONSTRUCTORS=y
-CONFIG_HAVE_IRQ_WORK=y
-CONFIG_IRQ_WORK=y
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_CROSS_COMPILE=""
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_HAVE_KERNEL_GZIP=y
-CONFIG_HAVE_KERNEL_LZMA=y
-CONFIG_HAVE_KERNEL_LZO=y
-CONFIG_KERNEL_GZIP=y
-# CONFIG_KERNEL_LZMA is not set
-# CONFIG_KERNEL_LZO is not set
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_POSIX_MQUEUE_SYSCTL=y
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT is not set
-# CONFIG_HAVE_GENERIC_HARDIRQS is not set
-# CONFIG_SPARSE_IRQ is not set
-
-#
-# RCU Subsystem
-#
-CONFIG_TINY_RCU=y
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_CGROUPS is not set
-# CONFIG_NAMESPACES is not set
-# CONFIG_SYSFS_DEPRECATED is not set
-# CONFIG_RELAY is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_RD_GZIP=y
-# CONFIG_RD_BZIP2 is not set
-# CONFIG_RD_LZMA is not set
-# CONFIG_RD_LZO is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
-CONFIG_PANIC_TIMEOUT=0
-CONFIG_EMBEDDED=y
-CONFIG_UID16=y
-# CONFIG_SYSCTL_SYSCALL is not set
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_ASHMEM=y
-CONFIG_AIO=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_PERF_USE_VMALLOC=y
-
-#
-# Kernel Performance Events And Counters
-#
-CONFIG_PERF_EVENTS=y
-# CONFIG_PERF_COUNTERS is not set
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_COMPAT_BRK=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
-CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
-CONFIG_OPROFILE=y
-CONFIG_HAVE_OPROFILE=y
-CONFIG_KPROBES=y
-CONFIG_KRETPROBES=y
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
-CONFIG_HAVE_CLK=y
-CONFIG_HAVE_HW_BREAKPOINT=y
-
-#
-# GCOV-based kernel profiling
-#
-# CONFIG_GCOV_KERNEL is not set
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-# CONFIG_MODULE_FORCE_LOAD is not set
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_BLOCK=y
-CONFIG_LBDAF=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEV_INTEGRITY is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_DEADLINE is not set
-CONFIG_DEFAULT_CFQ=y
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="cfq"
-# CONFIG_INLINE_SPIN_TRYLOCK is not set
-# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
-# CONFIG_INLINE_SPIN_LOCK is not set
-# CONFIG_INLINE_SPIN_LOCK_BH is not set
-# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
-# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
-CONFIG_INLINE_SPIN_UNLOCK=y
-# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
-CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
-# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_READ_TRYLOCK is not set
-# CONFIG_INLINE_READ_LOCK is not set
-# CONFIG_INLINE_READ_LOCK_BH is not set
-# CONFIG_INLINE_READ_LOCK_IRQ is not set
-# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
-CONFIG_INLINE_READ_UNLOCK=y
-# CONFIG_INLINE_READ_UNLOCK_BH is not set
-CONFIG_INLINE_READ_UNLOCK_IRQ=y
-# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_WRITE_TRYLOCK is not set
-# CONFIG_INLINE_WRITE_LOCK is not set
-# CONFIG_INLINE_WRITE_LOCK_BH is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
-CONFIG_INLINE_WRITE_UNLOCK=y
-# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
-CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
-# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
-# CONFIG_MUTEX_SPIN_ON_OWNER is not set
-CONFIG_FREEZER=y
-
-#
-# System Type
-#
-CONFIG_MMU=y
-# CONFIG_ARCH_AAEC2000 is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_VEXPRESS is not set
-# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_BCMRING is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CNS3XXX is not set
-# CONFIG_ARCH_GEMINI is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_STMP3XXX is not set
-# CONFIG_ARCH_NETX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IXP23XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_DOVE is not set
-# CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_LOKI is not set
-# CONFIG_ARCH_LPC32XX is not set
-# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_MMP is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_W90X900 is not set
-# CONFIG_ARCH_NUC93X is not set
-# CONFIG_ARCH_TEGRA is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_SHMOBILE is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_S3C64XX is not set
-# CONFIG_ARCH_S5P64X0 is not set
-# CONFIG_ARCH_S5P6442 is not set
-# CONFIG_ARCH_S5PC100 is not set
-# CONFIG_ARCH_S5PV210 is not set
-# CONFIG_ARCH_S5PV310 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_TCC_926 is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_U300 is not set
-# CONFIG_ARCH_U8500 is not set
-# CONFIG_ARCH_NOMADIK is not set
-# CONFIG_ARCH_DAVINCI is not set
-CONFIG_ARCH_OMAP=y
-# CONFIG_PLAT_SPEAR is not set
-
-#
-# TI OMAP Common Features
-#
-CONFIG_ARCH_OMAP_OTG=y
-# CONFIG_ARCH_OMAP1 is not set
-CONFIG_ARCH_OMAP2PLUS=y
-
-#
-# OMAP Feature Selections
-#
-CONFIG_OMAP_SMARTREFLEX=y
-CONFIG_OMAP_SMARTREFLEX_CLASS3=y
-CONFIG_OMAP_RESET_CLOCKS=y
-CONFIG_OMAP_MUX=y
-CONFIG_OMAP_MUX_DEBUG=y
-CONFIG_OMAP_MUX_WARNINGS=y
-CONFIG_OMAP_MCBSP=y
-# CONFIG_OMAP_MBOX_FWK is not set
-CONFIG_OMAP_IOMMU=y
-# CONFIG_OMAP_IOMMU_DEBUG is not set
-# CONFIG_OMAP_MPU_TIMER is not set
-CONFIG_OMAP_32K_TIMER=y
-# CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE is not set
-CONFIG_OMAP_32K_TIMER_HZ=128
-CONFIG_OMAP_DM_TIMER=y
-# CONFIG_OMAP_PM_NONE is not set
-CONFIG_OMAP_PM_NOOP=y
-
-#
-# TI OMAP2/3/4 Specific Features
-#
-CONFIG_ARCH_OMAP2PLUS_TYPICAL=y
-# CONFIG_ARCH_OMAP2 is not set
-CONFIG_ARCH_OMAP3=y
-# CONFIG_ARCH_OMAP4 is not set
-# CONFIG_ARCH_TI81XX is not set
-CONFIG_ARCH_OMAP3430=y
-CONFIG_OMAP_PACKAGE_CBB=y
-
-#
-# OMAP Board Type
-#
-CONFIG_MACH_OMAP3_BEAGLE=y
-# CONFIG_MACH_DEVKIT8000 is not set
-# CONFIG_MACH_OMAP_LDP is not set
-# CONFIG_MACH_OMAP3530_LV_SOM is not set
-# CONFIG_MACH_OMAP3_TORPEDO is not set
-# CONFIG_MACH_OVERO is not set
-# CONFIG_MACH_OMAP3EVM is not set
-# CONFIG_MACH_FLASHBOARD is not set
-# CONFIG_MACH_OMAP3517EVM is not set
-# CONFIG_MACH_CRANEBOARD is not set
-# CONFIG_MACH_OMAP3_PANDORA is not set
-# CONFIG_MACH_OMAP3_TOUCHBOOK is not set
-# CONFIG_MACH_OMAP_3430SDP is not set
-# CONFIG_MACH_NOKIA_RM680 is not set
-# CONFIG_MACH_NOKIA_RX51 is not set
-# CONFIG_MACH_OMAP_ZOOM2 is not set
-# CONFIG_MACH_OMAP_ZOOM3 is not set
-# CONFIG_MACH_CM_T35 is not set
-# CONFIG_MACH_CM_T3517 is not set
-# CONFIG_MACH_IGEP0020 is not set
-# CONFIG_MACH_IGEP0030 is not set
-# CONFIG_MACH_SBC3530 is not set
-# CONFIG_MACH_OMAP_3630SDP is not set
-# CONFIG_OMAP3_EMU is not set
-CONFIG_OMAP3_PM_DISABLE_VT_SWITCH=y
-# CONFIG_OMAP3_SDRC_AC_TIMING is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_V7=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_THUMBEE=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_BPREDICT_DISABLE is not set
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_DMA_MEM_BUFFERABLE=y
-# CONFIG_ARM_ERRATA_430973 is not set
-# CONFIG_ARM_ERRATA_458693 is not set
-# CONFIG_ARM_ERRATA_460075 is not set
-# CONFIG_ARM_ERRATA_743622 is not set
-CONFIG_COMMON_CLKDEV=y
-# CONFIG_FIQ_DEBUGGER is not set
-
-#
-# Bus support
-#
-# CONFIG_PCI_SYSCALL is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_VMSPLIT_3G=y
-# CONFIG_VMSPLIT_2G is not set
-# CONFIG_VMSPLIT_1G is not set
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_HZ=128
-# CONFIG_THUMB2_KERNEL is not set
-CONFIG_AEABI=y
-CONFIG_OABI_COMPAT=y
-CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
-# CONFIG_HIGHMEM is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_HAVE_MEMBLOCK=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_PHYS_ADDR_T_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=0
-CONFIG_VIRT_TO_BUS=y
-# CONFIG_KSM is not set
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_FORCE_MAX_ZONEORDER=11
-# CONFIG_LEDS is not set
-CONFIG_ALIGNMENT_TRAP=y
-# CONFIG_UACCESS_WITH_MEMCPY is not set
-# CONFIG_SECCOMP is not set
-# CONFIG_CC_STACKPROTECTOR is not set
-# CONFIG_DEPRECATED_PARAM_STRUCT is not set
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
-# CONFIG_CMDLINE_FORCE is not set
-# CONFIG_XIP_KERNEL is not set
-CONFIG_KEXEC=y
-CONFIG_ATAGS_PROC=y
-# CONFIG_AUTO_ZRELADDR is not set
-
-#
-# CPU Power Management
-#
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_TABLE=y
-# CONFIG_CPU_FREQ_DEBUG is not set
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_FREQ_STAT_DETAILS=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-# CONFIG_CPU_FREQ_GOV_INTERACTIVE is not set
-# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_NEON=y
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
-CONFIG_HAVE_AOUT=y
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_MISC=y
-
-#
-# Power management options
-#
-CONFIG_PM=y
-CONFIG_PM_DEBUG=y
-# CONFIG_PM_ADVANCED_DEBUG is not set
-# CONFIG_PM_VERBOSE is not set
-CONFIG_CAN_PM_TRACE=y
-CONFIG_PM_SLEEP=y
-CONFIG_SUSPEND_NVS=y
-CONFIG_SUSPEND=y
-# CONFIG_PM_TEST_SUSPEND is not set
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_HAS_WAKELOCK=y
-CONFIG_HAS_EARLYSUSPEND=y
-CONFIG_WAKELOCK=y
-CONFIG_WAKELOCK_STAT=y
-CONFIG_USER_WAKELOCK=y
-CONFIG_EARLYSUSPEND=y
-# CONFIG_NO_USER_SPACE_SCREEN_ACCESS_CONTROL is not set
-# CONFIG_CONSOLE_EARLYSUSPEND is not set
-CONFIG_FB_EARLYSUSPEND=y
-# CONFIG_APM_EMULATION is not set
-CONFIG_PM_RUNTIME=y
-CONFIG_PM_OPS=y
-CONFIG_ARCH_HAS_OPP=y
-CONFIG_PM_OPP=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-# CONFIG_XFRM_STATISTICS is not set
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE_DEMUX is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-CONFIG_INET_TUNNEL=y
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-# CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
-CONFIG_IPV6=y
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_IPV6_ROUTER_PREF is not set
-# CONFIG_IPV6_OPTIMISTIC_DAD is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_IPV6_MIP6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-CONFIG_INET6_XFRM_MODE_TRANSPORT=y
-CONFIG_INET6_XFRM_MODE_TUNNEL=y
-CONFIG_INET6_XFRM_MODE_BEET=y
-# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
-CONFIG_IPV6_SIT=y
-# CONFIG_IPV6_SIT_6RD is not set
-CONFIG_IPV6_NDISC_NODETYPE=y
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_MULTIPLE_TABLES is not set
-# CONFIG_IPV6_MROUTE is not set
-# CONFIG_NETLABEL is not set
-CONFIG_ANDROID_PARANOID_NETWORK=y
-CONFIG_NET_ACTIVITY_STATS=y
-# CONFIG_NETWORK_SECMARK is not set
-# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_SCTP is not set
-# CONFIG_RDS is not set
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_L2TP is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_NET_DSA is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_PHONET is not set
-# CONFIG_IEEE802154 is not set
-# CONFIG_NET_SCHED is not set
-# CONFIG_DCB is not set
-CONFIG_DNS_RESOLVER=y
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_TCPPROBE is not set
-# CONFIG_NET_DROP_MONITOR is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_AF_RXRPC is not set
-CONFIG_WIRELESS=y
-CONFIG_WIRELESS_EXT=y
-CONFIG_WEXT_CORE=y
-CONFIG_WEXT_PROC=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_EXT_SYSFS=y
-# CONFIG_LIB80211 is not set
-
-#
-# CFG80211 needs to be enabled for MAC80211
-#
-
-#
-# Some wireless drivers require a rate control algorithm
-#
-# CONFIG_WIMAX is not set
-# CONFIG_RFKILL is not set
-# CONFIG_NET_9P is not set
-# CONFIG_CAIF is not set
-# CONFIG_CEPH_LIB is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_DEVTMPFS is not set
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-CONFIG_FIRMWARE_IN_KERNEL=y
-CONFIG_EXTRA_FIRMWARE=""
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_TESTS is not set
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-# CONFIG_MTD_AR7_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-# CONFIG_RFD_FTL is not set
-# CONFIG_SSFDC is not set
-# CONFIG_SM_FTL is not set
-CONFIG_MTD_OOPS=y
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_DATAFLASH is not set
-# CONFIG_MTD_M25P80 is not set
-# CONFIG_MTD_SST25L is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-CONFIG_MTD_NAND_IDS=y
-CONFIG_MTD_NAND_ECC=y
-# CONFIG_MTD_NAND_ECC_SMC is not set
-CONFIG_MTD_NAND=y
-# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-# CONFIG_MTD_SM_COMMON is not set
-# CONFIG_MTD_NAND_MUSEUM_IDS is not set
-# CONFIG_MTD_NAND_GPIO is not set
-CONFIG_MTD_NAND_OMAP2=y
-# CONFIG_MTD_NAND_DISKONCHIP is not set
-# CONFIG_MTD_NAND_NANDSIM is not set
-# CONFIG_MTD_NAND_PLATFORM is not set
-# CONFIG_MTD_ALAUDA is not set
-CONFIG_MTD_ONENAND=y
-CONFIG_MTD_ONENAND_VERIFY_WRITE=y
-# CONFIG_MTD_ONENAND_GENERIC is not set
-CONFIG_MTD_ONENAND_OMAP2=y
-# CONFIG_MTD_ONENAND_OTP is not set
-# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
-# CONFIG_MTD_ONENAND_SIM is not set
-
-#
-# LPDDR flash memory drivers
-#
-# CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_UBI is not set
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-
-#
-# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
-#
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=16384
-# CONFIG_BLK_DEV_XIP is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-# CONFIG_MG_DISK is not set
-# CONFIG_BLK_DEV_RBD is not set
-# CONFIG_MISC_DEVICES is not set
-CONFIG_HAVE_IDE=y
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI_MOD=y
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_TGT is not set
-# CONFIG_SCSI_NETLINK is not set
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_SCH is not set
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-CONFIG_SCSI_SCAN_ASYNC=y
-CONFIG_SCSI_WAIT_SCAN=m
-
-#
-# SCSI Transports
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_ISCSI_BOOT_SYSFS is not set
-# CONFIG_LIBFC is not set
-# CONFIG_LIBFCOE is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_DH is not set
-# CONFIG_SCSI_OSD_INITIATOR is not set
-# CONFIG_ATA is not set
-CONFIG_MD=y
-# CONFIG_BLK_DEV_MD is not set
-CONFIG_BLK_DEV_DM=y
-# CONFIG_DM_DEBUG is not set
-CONFIG_DM_CRYPT=y
-# CONFIG_DM_SNAPSHOT is not set
-# CONFIG_DM_MIRROR is not set
-# CONFIG_DM_ZERO is not set
-# CONFIG_DM_MULTIPATH is not set
-# CONFIG_DM_DELAY is not set
-CONFIG_DM_UEVENT=y
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_VETH is not set
-CONFIG_MII=y
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_QSEMI_PHY is not set
-# CONFIG_LXT_PHY is not set
-# CONFIG_CICADA_PHY is not set
-# CONFIG_VITESSE_PHY is not set
-CONFIG_SMSC_PHY=y
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_BCM63XX_PHY is not set
-# CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
-# CONFIG_NATIONAL_PHY is not set
-# CONFIG_STE10XP is not set
-# CONFIG_LSI_ET1011C_PHY is not set
-# CONFIG_MICREL_PHY is not set
-# CONFIG_FIXED_PHY is not set
-# CONFIG_MDIO_BITBANG is not set
-CONFIG_NET_ETHERNET=y
-# CONFIG_AX88796 is not set
-# CONFIG_SMC91X is not set
-# CONFIG_DM9000 is not set
-# CONFIG_ENC28J60 is not set
-# CONFIG_ETHOC is not set
-CONFIG_SMC911X=y
-CONFIG_SMSC911X=y
-# CONFIG_SMSC911X_ARCH_HOOKS is not set
-# CONFIG_DNET is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
-# CONFIG_B44 is not set
-# CONFIG_KS8851 is not set
-# CONFIG_KS8851_MLL is not set
-CONFIG_NETDEV_1000=y
-CONFIG_TI_DAVINCI_EMAC=y
-CONFIG_TI_DAVINCI_MDIO=y
-CONFIG_TI_DAVINCI_CPDMA=y
-# CONFIG_STMMAC_ETH is not set
-CONFIG_NETDEV_10000=y
-CONFIG_WLAN=y
-# CONFIG_USB_ZD1201 is not set
-# CONFIG_BCM4329 is not set
-# CONFIG_HOSTAP is not set
-CONFIG_WL12XX_PLATFORM_DATA=y
-
-#
-# Enable WiMAX (Networking options) to see the WiMAX drivers
-#
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-CONFIG_USB_USBNET=y
-CONFIG_USB_NET_AX8817X=y
-CONFIG_USB_NET_CDCETHER=y
-# CONFIG_USB_NET_CDC_EEM is not set
-# CONFIG_USB_NET_DM9601 is not set
-# CONFIG_USB_NET_SMSC75XX is not set
-CONFIG_USB_NET_SMSC95XX=y
-# CONFIG_USB_NET_GL620A is not set
-CONFIG_USB_NET_NET1080=y
-# CONFIG_USB_NET_PLUSB is not set
-# CONFIG_USB_NET_MCS7830 is not set
-# CONFIG_USB_NET_RNDIS_HOST is not set
-CONFIG_USB_NET_CDC_SUBSET=y
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_BELKIN=y
-CONFIG_USB_ARMLINUX=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_KC2190=y
-CONFIG_USB_NET_ZAURUS=y
-# CONFIG_USB_NET_CX82310_ETH is not set
-# CONFIG_USB_NET_INT51X1 is not set
-# CONFIG_USB_IPHETH is not set
-# CONFIG_USB_SIERRA_NET is not set
-# CONFIG_WAN is not set
-
-#
-# CAIF transport drivers
-#
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_ISDN is not set
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-# CONFIG_INPUT_SPARSEKMAP is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_JOYDEV=y
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_EVBUG is not set
-# CONFIG_INPUT_KEYRESET is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-# CONFIG_KEYBOARD_ADP5588 is not set
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_QT2160 is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_KEYBOARD_GPIO_POLLED is not set
-# CONFIG_KEYBOARD_TCA6416 is not set
-# CONFIG_KEYBOARD_MATRIX is not set
-# CONFIG_KEYBOARD_MAX7359 is not set
-# CONFIG_KEYBOARD_MCS is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_OPENCORES is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
-CONFIG_KEYBOARD_TWL4030=y
-# CONFIG_KEYBOARD_XTKBD is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-CONFIG_MOUSE_PS2_ALPS=y
-CONFIG_MOUSE_PS2_LOGIPS2PP=y
-CONFIG_MOUSE_PS2_SYNAPTICS=y
-CONFIG_MOUSE_PS2_TRACKPOINT=y
-# CONFIG_MOUSE_PS2_ELANTECH is not set
-# CONFIG_MOUSE_PS2_SENTELIC is not set
-# CONFIG_MOUSE_PS2_TOUCHKIT is not set
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_APPLETOUCH is not set
-# CONFIG_MOUSE_BCM5974 is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_MOUSE_GPIO is not set
-# CONFIG_MOUSE_SYNAPTICS_I2C is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-# CONFIG_TOUCHSCREEN_ADS7846 is not set
-# CONFIG_TOUCHSCREEN_AD7877 is not set
-# CONFIG_TOUCHSCREEN_AD7879 is not set
-# CONFIG_TOUCHSCREEN_BU21013 is not set
-# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
-# CONFIG_TOUCHSCREEN_DYNAPRO is not set
-# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
-# CONFIG_TOUCHSCREEN_EETI is not set
-# CONFIG_TOUCHSCREEN_FUJITSU is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
-# CONFIG_TOUCHSCREEN_MCS5000 is not set
-# CONFIG_TOUCHSCREEN_MTOUCH is not set
-# CONFIG_TOUCHSCREEN_INEXIO is not set
-# CONFIG_TOUCHSCREEN_MK712 is not set
-# CONFIG_TOUCHSCREEN_PENMOUNT is not set
-# CONFIG_TOUCHSCREEN_QT602240 is not set
-CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y
-# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
-# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
-# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
-# CONFIG_TOUCHSCREEN_TSC2007 is not set
-# CONFIG_TOUCHSCREEN_TSC2004 is not set
-# CONFIG_TOUCHSCREEN_W90X900 is not set
-# CONFIG_TOUCHSCREEN_TPS6507X is not set
-CONFIG_INPUT_MISC=y
-# CONFIG_INPUT_AD714X is not set
-# CONFIG_INPUT_ATI_REMOTE is not set
-# CONFIG_INPUT_ATI_REMOTE2 is not set
-# CONFIG_INPUT_KEYCHORD is not set
-# CONFIG_INPUT_KEYSPAN_REMOTE is not set
-# CONFIG_INPUT_POWERMATE is not set
-# CONFIG_INPUT_YEALINK is not set
-# CONFIG_INPUT_CM109 is not set
-CONFIG_INPUT_TWL4030_PWRBUTTON=y
-# CONFIG_INPUT_TWL4030_VIBRA is not set
-# CONFIG_INPUT_UINPUT is not set
-# CONFIG_INPUT_GPIO is not set
-# CONFIG_INPUT_PCF8574 is not set
-# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
-# CONFIG_INPUT_ADXL34X is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_SERIO_ALTERA_PS2 is not set
-# CONFIG_SERIO_PS2MULT is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_DEVMEM=y
-CONFIG_DEVKMEM=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_N_GSM is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_RSA=y
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_MAX3100 is not set
-# CONFIG_SERIAL_MAX3107 is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_SERIAL_OMAP=y
-CONFIG_SERIAL_OMAP_CONSOLE=y
-# CONFIG_SERIAL_TIMBERDALE is not set
-# CONFIG_SERIAL_ALTERA_JTAGUART is not set
-# CONFIG_SERIAL_ALTERA_UART is not set
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_TTY_PRINTK is not set
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
-# CONFIG_HW_RANDOM_TIMERIOMEM is not set
-# CONFIG_R3964 is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_TCG_TPM is not set
-# CONFIG_TI81XX_HDMI is not set
-# CONFIG_DCC_TTY is not set
-# CONFIG_RAMOOPS is not set
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_CHARDEV=y
-# CONFIG_I2C_MUX is not set
-CONFIG_I2C_HELPER_AUTO=y
-
-#
-# I2C Hardware Bus support
-#
-
-#
-# I2C system bus drivers (mostly embedded / system-on-chip)
-#
-# CONFIG_I2C_DESIGNWARE is not set
-# CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_OCORES is not set
-CONFIG_I2C_OMAP=y
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_SIMTEC is not set
-# CONFIG_I2C_XILINX is not set
-
-#
-# External I2C/SMBus adapter drivers
-#
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_TINY_USB is not set
-
-#
-# Other I2C/SMBus bus drivers
-#
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-
-#
-# SPI Master Controller Drivers
-#
-# CONFIG_SPI_BITBANG is not set
-# CONFIG_SPI_GPIO is not set
-CONFIG_SPI_OMAP24XX=y
-# CONFIG_SPI_XILINX is not set
-# CONFIG_SPI_DESIGNWARE is not set
-
-#
-# SPI Protocol Masters
-#
-# CONFIG_SPI_SPIDEV is not set
-# CONFIG_SPI_TLE62X0 is not set
-
-#
-# PPS support
-#
-# CONFIG_PPS is not set
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_SYSFS=y
-
-#
-# Memory mapped GPIO expanders:
-#
-# CONFIG_GPIO_BASIC_MMIO is not set
-# CONFIG_GPIO_IT8761E is not set
-# CONFIG_GPIO_VX855 is not set
-
-#
-# I2C GPIO expanders:
-#
-# CONFIG_GPIO_MAX7300 is not set
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_PCA953X is not set
-# CONFIG_GPIO_PCF857X is not set
-# CONFIG_GPIO_SX150X is not set
-CONFIG_GPIO_TWL4030=y
-# CONFIG_GPIO_ADP5588 is not set
-
-#
-# PCI GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-# CONFIG_GPIO_MAX7301 is not set
-# CONFIG_GPIO_MCP23S08 is not set
-# CONFIG_GPIO_MC33880 is not set
-# CONFIG_GPIO_74X164 is not set
-
-#
-# AC97 GPIO expanders:
-#
-
-#
-# MODULbus GPIO expanders:
-#
-# CONFIG_W1 is not set
-CONFIG_POWER_SUPPLY=y
-# CONFIG_POWER_SUPPLY_DEBUG is not set
-# CONFIG_PDA_POWER is not set
-# CONFIG_TEST_POWER is not set
-# CONFIG_BATTERY_DS2782 is not set
-# CONFIG_BATTERY_BQ20Z75 is not set
-# CONFIG_BATTERY_BQ27x00 is not set
-# CONFIG_BATTERY_MAX17040 is not set
-# CONFIG_CHARGER_ISP1704 is not set
-# CONFIG_CHARGER_TWL4030 is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Native drivers
-#
-# CONFIG_SENSORS_AD7414 is not set
-# CONFIG_SENSORS_AD7418 is not set
-# CONFIG_SENSORS_ADCXX is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1029 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ADT7411 is not set
-# CONFIG_SENSORS_ADT7462 is not set
-# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7475 is not set
-# CONFIG_SENSORS_ASC7621 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_F75375S is not set
-# CONFIG_SENSORS_G760A is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_GPIO_FAN is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_JC42 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM70 is not set
-# CONFIG_SENSORS_LM73 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_LM93 is not set
-# CONFIG_SENSORS_LTC4215 is not set
-# CONFIG_SENSORS_LTC4245 is not set
-# CONFIG_SENSORS_LTC4261 is not set
-# CONFIG_SENSORS_LM95241 is not set
-# CONFIG_SENSORS_MAX1111 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_MAX6650 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_SHT15 is not set
-# CONFIG_SENSORS_SMM665 is not set
-# CONFIG_SENSORS_DME1737 is not set
-# CONFIG_SENSORS_EMC1403 is not set
-# CONFIG_SENSORS_EMC2103 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47M192 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_ADS7828 is not set
-# CONFIG_SENSORS_ADS7871 is not set
-# CONFIG_SENSORS_AMC6821 is not set
-# CONFIG_SENSORS_THMC50 is not set
-# CONFIG_SENSORS_TMP102 is not set
-# CONFIG_SENSORS_TMP401 is not set
-# CONFIG_SENSORS_TMP421 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83791D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
-# CONFIG_SENSORS_W83795 is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83L786NG is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_SENSORS_LIS3_SPI is not set
-# CONFIG_SENSORS_LIS3_I2C is not set
-# CONFIG_THERMAL is not set
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-CONFIG_OMAP_WATCHDOG=y
-CONFIG_TWL4030_WATCHDOG=y
-# CONFIG_MAX63XX_WATCHDOG is not set
-
-#
-# USB-based Watchdog Cards
-#
-# CONFIG_USBPCWATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
-CONFIG_MFD_SUPPORT=y
-CONFIG_MFD_CORE=y
-# CONFIG_MFD_88PM860X is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_HTC_EGPIO is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_HTC_I2CPLD is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_TPS6507X is not set
-CONFIG_TWL4030_CORE=y
-CONFIG_TWL4030_POWER=y
-CONFIG_TWL4030_SCRIPT=y
-CONFIG_TWL4030_CODEC=y
-# CONFIG_TWL6030_PWM is not set
-# CONFIG_MFD_STMPE is not set
-# CONFIG_MFD_TC35892 is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_T7L66XB is not set
-# CONFIG_MFD_TC6387XB is not set
-# CONFIG_MFD_TC6393XB is not set
-# CONFIG_PMIC_DA903X is not set
-# CONFIG_PMIC_ADP5520 is not set
-# CONFIG_MFD_MAX8925 is not set
-# CONFIG_MFD_MAX8998 is not set
-# CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM831X_I2C is not set
-# CONFIG_MFD_WM831X_SPI is not set
-# CONFIG_MFD_WM8350_I2C is not set
-# CONFIG_MFD_WM8994 is not set
-# CONFIG_MFD_PCF50633 is not set
-# CONFIG_MFD_MC13XXX is not set
-# CONFIG_ABX500_CORE is not set
-# CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_TPS6586X is not set
-CONFIG_REGULATOR=y
-# CONFIG_REGULATOR_DEBUG is not set
-CONFIG_REGULATOR_DUMMY=y
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
-# CONFIG_REGULATOR_BQ24022 is not set
-# CONFIG_REGULATOR_MAX1586 is not set
-# CONFIG_REGULATOR_MAX8649 is not set
-# CONFIG_REGULATOR_MAX8660 is not set
-# CONFIG_REGULATOR_MAX8952 is not set
-CONFIG_REGULATOR_TWL4030=y
-# CONFIG_REGULATOR_LP3971 is not set
-# CONFIG_REGULATOR_LP3972 is not set
-# CONFIG_REGULATOR_TPS65023 is not set
-# CONFIG_REGULATOR_TPS6507X is not set
-# CONFIG_REGULATOR_ISL6271A is not set
-# CONFIG_REGULATOR_AD5398 is not set
-CONFIG_MEDIA_SUPPORT=y
-
-#
-# Multimedia core support
-#
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_VIDEO_DEV=y
-CONFIG_VIDEO_V4L2_COMMON=y
-CONFIG_VIDEO_ALLOW_V4L1=y
-CONFIG_VIDEO_V4L1_COMPAT=y
-CONFIG_VIDEO_V4L2_SUBDEV_API=y
-# CONFIG_DVB_CORE is not set
-CONFIG_VIDEO_MEDIA=y
-
-#
-# Multimedia drivers
-#
-# CONFIG_IR_CORE is not set
-# CONFIG_MEDIA_ATTACH is not set
-CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
-CONFIG_MEDIA_TUNER_SIMPLE=y
-CONFIG_MEDIA_TUNER_TDA8290=y
-CONFIG_MEDIA_TUNER_TDA827X=y
-CONFIG_MEDIA_TUNER_TDA18271=y
-CONFIG_MEDIA_TUNER_TDA9887=y
-CONFIG_MEDIA_TUNER_TEA5761=y
-CONFIG_MEDIA_TUNER_TEA5767=y
-CONFIG_MEDIA_TUNER_MT20XX=y
-CONFIG_MEDIA_TUNER_XC2028=y
-CONFIG_MEDIA_TUNER_XC5000=y
-CONFIG_MEDIA_TUNER_MC44S803=y
-CONFIG_VIDEO_V4L2=y
-CONFIG_VIDEO_V4L1=y
-CONFIG_VIDEOBUF_GEN=y
-CONFIG_VIDEOBUF_DMA_CONTIG=y
-CONFIG_VIDEO_CAPTURE_DRIVERS=y
-# CONFIG_VIDEO_ADV_DEBUG is not set
-# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
-# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
-
-#
-# Encoders/decoders and other helper chips
-#
-
-#
-# Audio decoders
-#
-# CONFIG_VIDEO_TVAUDIO is not set
-# CONFIG_VIDEO_TDA7432 is not set
-# CONFIG_VIDEO_TDA9840 is not set
-# CONFIG_VIDEO_TDA9875 is not set
-# CONFIG_VIDEO_TEA6415C is not set
-# CONFIG_VIDEO_TEA6420 is not set
-# CONFIG_VIDEO_MSP3400 is not set
-# CONFIG_VIDEO_CS5345 is not set
-# CONFIG_VIDEO_CS53L32A is not set
-# CONFIG_VIDEO_M52790 is not set
-# CONFIG_VIDEO_TLV320AIC23B is not set
-# CONFIG_VIDEO_WM8775 is not set
-# CONFIG_VIDEO_WM8739 is not set
-# CONFIG_VIDEO_VP27SMPX is not set
-
-#
-# RDS decoders
-#
-# CONFIG_VIDEO_SAA6588 is not set
-
-#
-# Video decoders
-#
-# CONFIG_VIDEO_ADV7180 is not set
-# CONFIG_VIDEO_BT819 is not set
-# CONFIG_VIDEO_BT856 is not set
-# CONFIG_VIDEO_BT866 is not set
-# CONFIG_VIDEO_KS0127 is not set
-# CONFIG_VIDEO_OV7670 is not set
-# CONFIG_VIDEO_MT9T001 is not set
-CONFIG_VIDEO_MT9V011=y
-# CONFIG_VIDEO_MT9V032 is not set
-CONFIG_VIDEO_MT9V113=y
-# CONFIG_VIDEO_MT9T111 is not set
-# CONFIG_VIDEO_TCM825X is not set
-# CONFIG_VIDEO_SAA7110 is not set
-# CONFIG_VIDEO_SAA711X is not set
-# CONFIG_VIDEO_SAA717X is not set
-# CONFIG_VIDEO_SAA7191 is not set
-# CONFIG_VIDEO_TVP514X is not set
-# CONFIG_VIDEO_TVP5150 is not set
-# CONFIG_VIDEO_TVP7002 is not set
-# CONFIG_VIDEO_VPX3220 is not set
-
-#
-# Video and audio decoders
-#
-# CONFIG_VIDEO_CX25840 is not set
-
-#
-# MPEG video encoders
-#
-# CONFIG_VIDEO_CX2341X is not set
-
-#
-# Video encoders
-#
-# CONFIG_VIDEO_SAA7127 is not set
-# CONFIG_VIDEO_SAA7185 is not set
-# CONFIG_VIDEO_ADV7170 is not set
-# CONFIG_VIDEO_ADV7175 is not set
-# CONFIG_VIDEO_THS7303 is not set
-# CONFIG_VIDEO_ADV7343 is not set
-# CONFIG_VIDEO_AK881X is not set
-
-#
-# Video improvement chips
-#
-# CONFIG_VIDEO_UPD64031A is not set
-# CONFIG_VIDEO_UPD64083 is not set
-# CONFIG_VIDEO_VPSS_SYSTEM is not set
-# CONFIG_VIDEO_VPFE_CAPTURE is not set
-CONFIG_VIDEO_OMAP2_VOUT=y
-# CONFIG_VIDEO_CPIA2 is not set
-# CONFIG_VIDEO_SR030PC30 is not set
-CONFIG_VIDEO_OMAP3=y
-CONFIG_VIDEO_OMAP3_DEBUG=y
-# CONFIG_SOC_CAMERA is not set
-CONFIG_V4L_USB_DRIVERS=y
-CONFIG_USB_VIDEO_CLASS=y
-CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
-# CONFIG_USB_GSPCA is not set
-# CONFIG_VIDEO_PVRUSB2 is not set
-# CONFIG_VIDEO_HDPVR is not set
-# CONFIG_VIDEO_USBVISION is not set
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_ET61X251 is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_SN9C102 is not set
-# CONFIG_USB_PWC is not set
-# CONFIG_USB_ZR364XX is not set
-# CONFIG_USB_STKWEBCAM is not set
-# CONFIG_USB_S2255 is not set
-# CONFIG_V4L_MEM2MEM_DRIVERS is not set
-# CONFIG_RADIO_ADAPTERS is not set
-# CONFIG_DAB is not set
-
-#
-# Graphics support
-#
-# CONFIG_DRM is not set
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
-# CONFIG_FB_DDC is not set
-# CONFIG_FB_BOOT_VESA_SUPPORT is not set
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
-# CONFIG_FB_SYS_FILLRECT is not set
-# CONFIG_FB_SYS_COPYAREA is not set
-# CONFIG_FB_SYS_IMAGEBLIT is not set
-# CONFIG_FB_FOREIGN_ENDIAN is not set
-# CONFIG_FB_SYS_FOPS is not set
-# CONFIG_FB_SVGALIB is not set
-# CONFIG_FB_MACMODES is not set
-# CONFIG_FB_BACKLIGHT is not set
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_TILEBLITTING=y
-
-#
-# Frame buffer hardware drivers
-#
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_TMIO is not set
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FB_METRONOME is not set
-# CONFIG_FB_MB862XX is not set
-# CONFIG_FB_BROADSHEET is not set
-# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
-CONFIG_OMAP2_VRAM=y
-CONFIG_OMAP2_VRFB=y
-CONFIG_OMAP2_DSS=y
-CONFIG_OMAP2_VRAM_SIZE=4
-CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y
-# CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS is not set
-CONFIG_OMAP2_DSS_DPI=y
-# CONFIG_OMAP2_DSS_RFBI is not set
-CONFIG_OMAP2_DSS_VENC=y
-CONFIG_OMAP2_VENC_OUT_TYPE_SVIDEO=y
-# CONFIG_OMAP2_VENC_OUT_TYPE_COMPOSITE is not set
-# CONFIG_OMAP2_DSS_SDI is not set
-CONFIG_OMAP2_DSS_DSI=y
-CONFIG_OMAP2_DSS_USE_DSI_PLL=y
-# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
-CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=1
-CONFIG_FB_OMAP2=y
-CONFIG_FB_OMAP2_DEBUG_SUPPORT=y
-CONFIG_FB_OMAP2_NUM_FBS=1
-
-#
-# OMAP2/3 Display Device Drivers
-#
-CONFIG_PANEL_GENERIC=y
-# CONFIG_PANEL_LGPHILIPS_LB035Q02 is not set
-# CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C is not set
-CONFIG_PANEL_SHARP_LS037V7DW01=y
-# CONFIG_PANEL_SHARP_LQ043T1DG01 is not set
-# CONFIG_PANEL_SAMSUNG_LMS700KF23 is not set
-# CONFIG_PANEL_TAAL is not set
-# CONFIG_PANEL_TOPPOLY_TDO35S is not set
-# CONFIG_PANEL_TPO_TD043MTEA1 is not set
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-# CONFIG_LCD_L4F00242T03 is not set
-# CONFIG_LCD_LMS283GF05 is not set
-# CONFIG_LCD_LTV350QV is not set
-# CONFIG_LCD_TDO24M is not set
-# CONFIG_LCD_VGG2432A4 is not set
-CONFIG_LCD_PLATFORM=y
-# CONFIG_LCD_S6E63M0 is not set
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_GENERIC=m
-# CONFIG_BACKLIGHT_ADP8860 is not set
-
-#
-# Display device support
-#
-CONFIG_DISPLAY_SUPPORT=y
-
-#
-# Display hardware drivers
-#
-
-#
-# Console display driver support
-#
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE is not set
-CONFIG_LOGO=y
-CONFIG_LOGO_LINUX_MONO=y
-CONFIG_LOGO_LINUX_VGA16=y
-CONFIG_LOGO_LINUX_CLUT224=y
-CONFIG_SOUND=y
-# CONFIG_SOUND_OSS_CORE is not set
-CONFIG_SND=y
-CONFIG_SND_TIMER=y
-CONFIG_SND_PCM=y
-CONFIG_SND_HWDEP=y
-CONFIG_SND_RAWMIDI=y
-CONFIG_SND_JACK=y
-# CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_PCM_OSS is not set
-# CONFIG_SND_HRTIMER is not set
-# CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
-CONFIG_SND_VERBOSE_PROCFS=y
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-# CONFIG_SND_RAWMIDI_SEQ is not set
-# CONFIG_SND_OPL3_LIB_SEQ is not set
-# CONFIG_SND_OPL4_LIB_SEQ is not set
-# CONFIG_SND_SBAWE_SEQ is not set
-# CONFIG_SND_EMU10K1_SEQ is not set
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_ALOOP is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-CONFIG_SND_ARM=y
-CONFIG_SND_SPI=y
-CONFIG_SND_USB=y
-CONFIG_SND_USB_AUDIO=y
-# CONFIG_SND_USB_UA101 is not set
-# CONFIG_SND_USB_CAIAQ is not set
-CONFIG_SND_SOC=y
-CONFIG_SND_OMAP_SOC=y
-CONFIG_SND_OMAP_SOC_MCBSP=y
-CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE=y
-CONFIG_SND_SOC_I2C_AND_SPI=y
-# CONFIG_SND_SOC_ALL_CODECS is not set
-CONFIG_SND_SOC_TWL4030=y
-# CONFIG_SND_SOC_WL1271BT is not set
-# CONFIG_SOUND_PRIME is not set
-CONFIG_HID_SUPPORT=y
-CONFIG_HID=y
-# CONFIG_HIDRAW is not set
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=y
-# CONFIG_HID_PID is not set
-# CONFIG_USB_HIDDEV is not set
-
-#
-# Special HID drivers
-#
-# CONFIG_HID_3M_PCT is not set
-# CONFIG_HID_A4TECH is not set
-# CONFIG_HID_ACRUX_FF is not set
-# CONFIG_HID_APPLE is not set
-# CONFIG_HID_BELKIN is not set
-# CONFIG_HID_CANDO is not set
-# CONFIG_HID_CHERRY is not set
-# CONFIG_HID_CHICONY is not set
-# CONFIG_HID_PRODIKEYS is not set
-# CONFIG_HID_CYPRESS is not set
-# CONFIG_HID_DRAGONRISE is not set
-# CONFIG_HID_EGALAX is not set
-# CONFIG_HID_EZKEY is not set
-# CONFIG_HID_KYE is not set
-# CONFIG_HID_UCLOGIC is not set
-# CONFIG_HID_WALTOP is not set
-# CONFIG_HID_GYRATION is not set
-# CONFIG_HID_TWINHAN is not set
-# CONFIG_HID_KENSINGTON is not set
-# CONFIG_HID_LOGITECH is not set
-# CONFIG_HID_MICROSOFT is not set
-# CONFIG_HID_MOSART is not set
-# CONFIG_HID_MONTEREY is not set
-# CONFIG_HID_NTRIG is not set
-# CONFIG_HID_ORTEK is not set
-# CONFIG_HID_PANTHERLORD is not set
-# CONFIG_HID_PETALYNX is not set
-# CONFIG_HID_PICOLCD is not set
-# CONFIG_HID_QUANTA is not set
-# CONFIG_HID_ROCCAT is not set
-# CONFIG_HID_ROCCAT_KONE is not set
-# CONFIG_HID_ROCCAT_PYRA is not set
-# CONFIG_HID_SAMSUNG is not set
-# CONFIG_HID_SONY is not set
-# CONFIG_HID_STANTUM is not set
-# CONFIG_HID_SUNPLUS is not set
-# CONFIG_HID_GREENASIA is not set
-# CONFIG_HID_SMARTJOYPLUS is not set
-# CONFIG_HID_TOPSEED is not set
-# CONFIG_HID_THRUSTMASTER is not set
-# CONFIG_HID_ZEROPLUS is not set
-# CONFIG_HID_ZYDACRON is not set
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_DEVICE_CLASS is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-CONFIG_USB_SUSPEND=y
-CONFIG_USB_OTG=y
-# CONFIG_USB_OTG_WHITELIST is not set
-# CONFIG_USB_OTG_BLACKLIST_HUB is not set
-CONFIG_USB_MON=y
-# CONFIG_USB_WUSB is not set
-# CONFIG_USB_WUSB_CBAF is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_C67X00_HCD is not set
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_EHCI_TT_NEWSCHED=y
-# CONFIG_USB_OXU210HP_HCD is not set
-# CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_ISP1760_HCD is not set
-# CONFIG_USB_ISP1362_HCD is not set
-# CONFIG_USB_OHCI_HCD is not set
-# CONFIG_USB_SL811_HCD is not set
-# CONFIG_USB_R8A66597_HCD is not set
-# CONFIG_USB_HWA_HCD is not set
-CONFIG_USB_MUSB_HDRC=y
-
-#
-# Platform Glue Layer
-#
-# CONFIG_USB_MUSB_TUSB6010_GLUE is not set
-CONFIG_USB_MUSB_OMAP2PLUS_GLUE=y
-# CONFIG_USB_MUSB_AM35X_GLUE is not set
-# CONFIG_USB_MUSB_DAVINCI is not set
-# CONFIG_USB_MUSB_DA8XX is not set
-# CONFIG_USB_MUSB_TUSB6010 is not set
-CONFIG_USB_MUSB_OMAP2PLUS=y
-# CONFIG_USB_MUSB_AM35X is not set
-# CONFIG_USB_MUSB_TI81XX is not set
-# CONFIG_USB_MUSB_BLACKFIN is not set
-# CONFIG_USB_MUSB_UX500 is not set
-# CONFIG_USB_MUSB_HOST is not set
-# CONFIG_USB_MUSB_PERIPHERAL is not set
-CONFIG_USB_MUSB_OTG=y
-CONFIG_USB_GADGET_MUSB_HDRC=y
-CONFIG_USB_MUSB_HDRC_HCD=y
-# CONFIG_MUSB_PIO_ONLY is not set
-CONFIG_USB_INVENTRA_DMA_HW=y
-# CONFIG_USB_TI_CPPI_DMA_HW is not set
-# CONFIG_USB_TI_CPPI41_DMA_HW is not set
-CONFIG_USB_INVENTRA_DMA=y
-CONFIG_MUSB_USE_SYSTEM_DMA_WORKAROUND=y
-# CONFIG_USB_TI_CPPI_DMA is not set
-# CONFIG_USB_TI_CPPI41_DMA is not set
-# CONFIG_USB_TUSB_OMAP_DMA is not set
-# CONFIG_USB_MUSB_DEBUG is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_WDM is not set
-# CONFIG_USB_TMC is not set
-
-#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
-#
-
-#
-# also be needed; see USB_STORAGE Help for more info
-#
-CONFIG_USB_STORAGE=y
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_ONETOUCH is not set
-# CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
-# CONFIG_USB_UAS is not set
-# CONFIG_USB_LIBUSUAL is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_SEVSEG is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYPRESS_CY7C63 is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_FTDI_ELAN is not set
-# CONFIG_USB_APPLEDISPLAY is not set
-# CONFIG_USB_SISUSBVGA is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_TEST is not set
-# CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_YUREX is not set
-CONFIG_USB_GADGET=y
-# CONFIG_USB_GADGET_DEBUG_FILES is not set
-# CONFIG_USB_GADGET_DEBUG_FS is not set
-CONFIG_USB_GADGET_VBUS_DRAW=2
-CONFIG_USB_GADGET_SELECTED=y
-# CONFIG_USB_GADGET_OMAP is not set
-# CONFIG_USB_GADGET_R8A66597 is not set
-# CONFIG_USB_GADGET_M66592 is not set
-# CONFIG_USB_GADGET_DUMMY_HCD is not set
-CONFIG_USB_GADGET_DUALSPEED=y
-# CONFIG_USB_ZERO is not set
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_ETH is not set
-# CONFIG_USB_GADGETFS is not set
-# CONFIG_USB_FUNCTIONFS is not set
-# CONFIG_USB_FILE_STORAGE is not set
-# CONFIG_USB_MASS_STORAGE is not set
-# CONFIG_USB_G_SERIAL is not set
-# CONFIG_USB_MIDI_GADGET is not set
-# CONFIG_USB_G_PRINTER is not set
-CONFIG_USB_ANDROID=y
-# CONFIG_USB_ANDROID_ACM is not set
-CONFIG_USB_ANDROID_ADB=y
-CONFIG_USB_ANDROID_MASS_STORAGE=y
-# CONFIG_USB_ANDROID_MTP is not set
-# CONFIG_USB_ANDROID_RNDIS is not set
-# CONFIG_USB_CDC_COMPOSITE is not set
-# CONFIG_USB_G_MULTI is not set
-# CONFIG_USB_G_HID is not set
-# CONFIG_USB_G_DBGP is not set
-# CONFIG_USB_G_WEBCAM is not set
-
-#
-# OTG and related infrastructure
-#
-CONFIG_USB_OTG_UTILS=y
-# CONFIG_USB_GPIO_VBUS is not set
-# CONFIG_ISP1301_OMAP is not set
-# CONFIG_USB_ULPI is not set
-CONFIG_TWL4030_USB=y
-# CONFIG_NOP_USB_XCEIV is not set
-CONFIG_MMC=y
-# CONFIG_MMC_DEBUG is not set
-CONFIG_MMC_UNSAFE_RESUME=y
-# CONFIG_MMC_EMBEDDED_SDIO is not set
-# CONFIG_MMC_PARANOID_SD_INIT is not set
-
-#
-# MMC/SD/SDIO Card Drivers
-#
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_BLOCK_MINORS=8
-CONFIG_MMC_BLOCK_BOUNCE=y
-# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set
-CONFIG_SDIO_UART=y
-# CONFIG_MMC_TEST is not set
-
-#
-# MMC/SD/SDIO Host Controller Drivers
-#
-# CONFIG_MMC_SDHCI is not set
-CONFIG_MMC_OMAP=y
-CONFIG_MMC_OMAP_HS=y
-# CONFIG_MMC_SPI is not set
-# CONFIG_MMC_USHC is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_NEW_LEDS is not set
-CONFIG_SWITCH=y
-# CONFIG_SWITCH_GPIO is not set
-# CONFIG_ACCESSIBILITY is not set
-CONFIG_RTC_LIB=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_HCTOSYS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
-# CONFIG_RTC_DEBUG is not set
-
-#
-# RTC interfaces
-#
-CONFIG_RTC_INTF_SYSFS=y
-CONFIG_RTC_INTF_PROC=y
-CONFIG_RTC_INTF_DEV=y
-# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
-CONFIG_RTC_INTF_ALARM=y
-CONFIG_RTC_INTF_ALARM_DEV=y
-# CONFIG_RTC_DRV_TEST is not set
-
-#
-# I2C RTC drivers
-#
-# CONFIG_RTC_DRV_DS1307 is not set
-# CONFIG_RTC_DRV_DS1374 is not set
-# CONFIG_RTC_DRV_DS1672 is not set
-# CONFIG_RTC_DRV_DS3232 is not set
-# CONFIG_RTC_DRV_MAX6900 is not set
-# CONFIG_RTC_DRV_RS5C372 is not set
-# CONFIG_RTC_DRV_ISL1208 is not set
-# CONFIG_RTC_DRV_ISL12022 is not set
-# CONFIG_RTC_DRV_X1205 is not set
-# CONFIG_RTC_DRV_PCF8563 is not set
-# CONFIG_RTC_DRV_PCF8583 is not set
-# CONFIG_RTC_DRV_M41T80 is not set
-# CONFIG_RTC_DRV_BQ32K is not set
-CONFIG_RTC_DRV_TWL4030=y
-# CONFIG_RTC_DRV_S35390A is not set
-# CONFIG_RTC_DRV_FM3130 is not set
-# CONFIG_RTC_DRV_RX8581 is not set
-# CONFIG_RTC_DRV_RX8025 is not set
-
-#
-# SPI RTC drivers
-#
-# CONFIG_RTC_DRV_M41T94 is not set
-# CONFIG_RTC_DRV_DS1305 is not set
-# CONFIG_RTC_DRV_DS1390 is not set
-# CONFIG_RTC_DRV_MAX6902 is not set
-# CONFIG_RTC_DRV_R9701 is not set
-# CONFIG_RTC_DRV_RS5C348 is not set
-# CONFIG_RTC_DRV_DS3234 is not set
-# CONFIG_RTC_DRV_PCF2123 is not set
-
-#
-# Platform RTC drivers
-#
-# CONFIG_RTC_DRV_CMOS is not set
-# CONFIG_RTC_DRV_DS1286 is not set
-# CONFIG_RTC_DRV_DS1511 is not set
-# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_DS1742 is not set
-# CONFIG_RTC_DRV_STK17TA8 is not set
-# CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_M48T35 is not set
-# CONFIG_RTC_DRV_M48T59 is not set
-# CONFIG_RTC_DRV_MSM6242 is not set
-# CONFIG_RTC_DRV_BQ4802 is not set
-# CONFIG_RTC_DRV_RP5C01 is not set
-# CONFIG_RTC_DRV_V3020 is not set
-
-#
-# on-CPU RTC drivers
-#
-# CONFIG_DMADEVICES is not set
-# CONFIG_AUXDISPLAY is not set
-# CONFIG_UIO is not set
-CONFIG_STAGING=y
-# CONFIG_STAGING_EXCLUDE_BUILD is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_USB_IP_COMMON is not set
-# CONFIG_ECHO is not set
-# CONFIG_BRCM80211 is not set
-# CONFIG_RT2870 is not set
-# CONFIG_COMEDI is not set
-# CONFIG_ASUS_OLED is not set
-# CONFIG_R8712U is not set
-# CONFIG_TRANZPORT is not set
-
-#
-# Android
-#
-CONFIG_ANDROID=y
-CONFIG_ANDROID_BINDER_IPC=y
-CONFIG_ANDROID_LOGGER=y
-CONFIG_ANDROID_RAM_CONSOLE=y
-CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE=y
-CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION=y
-CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE=128
-CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE=16
-CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE=8
-CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL=0x11d
-# CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT is not set
-CONFIG_ANDROID_TIMED_OUTPUT=y
-CONFIG_ANDROID_TIMED_GPIO=y
-CONFIG_ANDROID_LOW_MEMORY_KILLER=y
-# CONFIG_POHMELFS is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_LINE6_USB is not set
-# CONFIG_VT6656 is not set
-# CONFIG_FB_UDL is not set
-# CONFIG_IIO is not set
-# CONFIG_ZRAM is not set
-# CONFIG_BATMAN_ADV is not set
-# CONFIG_FB_SM7XX is not set
-
-#
-# Texas Instruments shared transport line discipline
-#
-# CONFIG_ADIS16255 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_EASYCAP is not set
-# CONFIG_TIDSPBRIDGE is not set
-# CONFIG_WESTBRIDGE is not set
-CONFIG_WESTBRIDGE_HAL_SELECTED=y
-CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL=y
-# CONFIG_MACH_NO_WESTBRIDGE is not set
-# CONFIG_ATH6K_LEGACY is not set
-# CONFIG_USB_ENESTORAGE is not set
-# CONFIG_BCM_WIMAX is not set
-# CONFIG_FT1000 is not set
-
-#
-# Speakup console speech
-#
-# CONFIG_SPEAKUP is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_XATTR=y
-# CONFIG_EXT4_FS_POSIX_ACL is not set
-# CONFIG_EXT4_FS_SECURITY is not set
-# CONFIG_EXT4_DEBUG is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-# CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_BTRFS_FS is not set
-# CONFIG_NILFS2_FS is not set
-CONFIG_FILE_LOCKING=y
-CONFIG_FSNOTIFY=y
-CONFIG_DNOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_FANOTIFY is not set
-CONFIG_QUOTA=y
-# CONFIG_QUOTA_NETLINK_INTERFACE is not set
-CONFIG_PRINT_QUOTA_WARNING=y
-# CONFIG_QUOTA_DEBUG is not set
-CONFIG_QUOTA_TREE=y
-# CONFIG_QFMT_V1 is not set
-CONFIG_QFMT_V2=y
-CONFIG_QUOTACTL=y
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
-
-#
-# Caches
-#
-# CONFIG_FSCACHE is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_ECRYPT_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_YAFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_FS_XATTR=y
-CONFIG_JFFS2_FS_POSIX_ACL=y
-CONFIG_JFFS2_FS_SECURITY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_RTIME=y
-CONFIG_JFFS2_RUBIN=y
-# CONFIG_JFFS2_CMODE_NONE is not set
-CONFIG_JFFS2_CMODE_PRIORITY=y
-# CONFIG_JFFS2_CMODE_SIZE is not set
-# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
-# CONFIG_LOGFS is not set
-CONFIG_CRAMFS=y
-# CONFIG_SQUASHFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-CONFIG_NETWORK_FILESYSTEMS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-# CONFIG_NFS_V4_1 is not set
-CONFIG_ROOT_NFS=y
-CONFIG_NFS_USE_LEGACY_DNS=y
-# CONFIG_NFS_USE_NEW_IDMAPPER is not set
-# CONFIG_NFSD is not set
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_NFS_ACL_SUPPORT=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-CONFIG_SUNRPC_GSS=y
-CONFIG_RPCSEC_GSS_KRB5=y
-# CONFIG_CEPH_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-# CONFIG_DLM is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_FRAME_WARN=1024
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_STRIP_ASM_SYMS is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_HARDLOCKUP_DETECTOR is not set
-CONFIG_BKL=y
-# CONFIG_SPARSE_RCU_POINTER is not set
-CONFIG_STACKTRACE=y
-CONFIG_DEBUG_BUGVERBOSE=y
-# CONFIG_DEBUG_MEMORY_INIT is not set
-CONFIG_FRAME_POINTER=y
-# CONFIG_LKDTM is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-CONFIG_NOP_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
-CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
-CONFIG_TRACING_SUPPORT=y
-CONFIG_FTRACE=y
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_ENABLE_DEFAULT_TRACERS is not set
-CONFIG_BRANCH_PROFILE_NONE=y
-# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
-# CONFIG_PROFILE_ALL_BRANCHES is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-CONFIG_KPROBE_EVENT=y
-# CONFIG_RING_BUFFER_BENCHMARK is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_ATOMIC64_SELFTEST is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_STRICT_DEVMEM is not set
-# CONFIG_ARM_UNWIND is not set
-# CONFIG_DEBUG_USER is not set
-# CONFIG_OC_ETM is not set
-
-#
-# Security options
-#
-CONFIG_KEYS=y
-# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
-# CONFIG_SECURITY_DMESG_RESTRICT is not set
-CONFIG_SECURITY=y
-# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_NETWORK is not set
-# CONFIG_SECURITY_PATH is not set
-# CONFIG_SECURITY_TOMOYO is not set
-# CONFIG_SECURITY_APPARMOR is not set
-# CONFIG_IMA is not set
-CONFIG_DEFAULT_SECURITY_DAC=y
-CONFIG_DEFAULT_SECURITY=""
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_ALGAPI2=y
-CONFIG_CRYPTO_AEAD2=y
-CONFIG_CRYPTO_BLKCIPHER=y
-CONFIG_CRYPTO_BLKCIPHER2=y
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_HASH2=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_PCOMP2=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_MANAGER2=y
-CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_NULL is not set
-CONFIG_CRYPTO_WORKQUEUE=y
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Authenticated Encryption with Associated Data
-#
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_SEQIV is not set
-
-#
-# Block modes
-#
-CONFIG_CRYPTO_CBC=y
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_CTS is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_XTS is not set
-
-#
-# Hash modes
-#
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_VMAC is not set
-
-#
-# Digest
-#
-CONFIG_CRYPTO_CRC32C=y
-# CONFIG_CRYPTO_GHASH is not set
-# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_RMD128 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RMD256 is not set
-# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_WP512 is not set
-
-#
-# Ciphers
-#
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-CONFIG_CRYPTO_DES=y
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_SALSA20 is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_TEA is not set
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_TWOFISH_COMMON=y
-
-#
-# Compression
-#
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_ZLIB is not set
-# CONFIG_CRYPTO_LZO is not set
-
-#
-# Random Number Generation
-#
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_CRYPTO_HW=y
-# CONFIG_CRYPTO_DEV_OMAP_SHAM is not set
-# CONFIG_CRYPTO_DEV_OMAP_AES is not set
-CONFIG_BINARY_PRINTF=y
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-CONFIG_GENERIC_FIND_LAST_BIT=y
-CONFIG_CRC_CCITT=y
-# CONFIG_CRC16 is not set
-# CONFIG_CRC_T10DIF is not set
-# CONFIG_CRC_ITU_T is not set
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-CONFIG_LIBCRC32C=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_REED_SOLOMON=y
-CONFIG_REED_SOLOMON_ENC8=y
-CONFIG_REED_SOLOMON_DEC8=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_NLATTR=y
diff --git a/kernel/arch/arm/configs/panda_defconfig b/kernel/arch/arm/configs/panda_defconfig
deleted file mode 100644
index 4c5e56c56cf6..000000000000
--- a/kernel/arch/arm/configs/panda_defconfig
+++ /dev/null
@@ -1,331 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_CGROUPS=y
-CONFIG_CGROUP_DEBUG=y
-CONFIG_CGROUP_FREEZER=y
-CONFIG_CGROUP_CPUACCT=y
-CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_PANIC_TIMEOUT=5
-CONFIG_ASHMEM=y
-# CONFIG_AIO is not set
-CONFIG_EMBEDDED=y
-# CONFIG_SLUB_DEBUG is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_FORCE_LOAD=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_OMAP_RESET_CLOCKS=y
-# CONFIG_ARCH_OMAP2 is not set
-# CONFIG_ARCH_OMAP3 is not set
-# CONFIG_MACH_OMAP_4430SDP is not set
-CONFIG_ARM_THUMBEE=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_SMP=y
-# CONFIG_SMP_ON_UP is not set
-CONFIG_NR_CPUS=2
-CONFIG_PREEMPT=y
-CONFIG_CMDLINE="console=ttyO2,115200n8 mem=1G androidboot.console=ttyO2"
-CONFIG_CMDLINE_EXTEND=y
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=y
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
-CONFIG_CPU_IDLE=y
-CONFIG_OMAP_SMARTREFLEX=y
-CONFIG_OMAP_SMARTREFLEX_CLASS1P5=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_BINFMT_MISC=y
-CONFIG_WAKELOCK=y
-CONFIG_PM_DEBUG=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_INET_ESP=y
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-CONFIG_IPV6=y
-CONFIG_IPV6_PRIVACY=y
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_OPTIMISTIC_DAD=y
-CONFIG_INET6_AH=y
-CONFIG_INET6_ESP=y
-CONFIG_INET6_IPCOMP=y
-CONFIG_IPV6_MIP6=y
-CONFIG_IPV6_TUNNEL=y
-CONFIG_IPV6_MULTIPLE_TABLES=y
-CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_LOG=y
-CONFIG_NETFILTER_TPROXY=y
-CONFIG_NF_CONNTRACK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_DCCP=y
-CONFIG_NF_CT_PROTO_SCTP=y
-CONFIG_NF_CT_PROTO_UDPLITE=y
-CONFIG_NF_CONNTRACK_AMANDA=y
-CONFIG_NF_CONNTRACK_FTP=y
-CONFIG_NF_CONNTRACK_H323=y
-CONFIG_NF_CONNTRACK_IRC=y
-CONFIG_NF_CONNTRACK_NETBIOS_NS=y
-CONFIG_NF_CONNTRACK_PPTP=y
-CONFIG_NF_CONNTRACK_SANE=y
-CONFIG_NF_CONNTRACK_TFTP=y
-CONFIG_NF_CT_NETLINK=y
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
-CONFIG_NETFILTER_XT_TARGET_MARK=y
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
-CONFIG_NETFILTER_XT_MATCH_COMMENT=y
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
-CONFIG_NETFILTER_XT_MATCH_HELPER=y
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
-CONFIG_NETFILTER_XT_MATCH_LENGTH=y
-CONFIG_NETFILTER_XT_MATCH_LIMIT=y
-CONFIG_NETFILTER_XT_MATCH_MAC=y
-CONFIG_NETFILTER_XT_MATCH_MARK=y
-CONFIG_NETFILTER_XT_MATCH_POLICY=y
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
-CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
-CONFIG_NETFILTER_XT_MATCH_QUOTA=y
-CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
-CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
-CONFIG_NETFILTER_XT_MATCH_SOCKET=y
-CONFIG_NETFILTER_XT_MATCH_STATE=y
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
-CONFIG_NETFILTER_XT_MATCH_STRING=y
-CONFIG_NETFILTER_XT_MATCH_TIME=y
-CONFIG_NETFILTER_XT_MATCH_U32=y
-CONFIG_NF_CONNTRACK_IPV4=y
-CONFIG_NF_CONNTRACK_IPV6=y
-CONFIG_IP_NF_IPTABLES=y
-CONFIG_IP_NF_MATCH_AH=y
-CONFIG_IP_NF_MATCH_ECN=y
-CONFIG_IP_NF_MATCH_TTL=y
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
-CONFIG_IP_NF_TARGET_REJECT_SKERR=y
-CONFIG_IP_NF_TARGET_LOG=y
-CONFIG_NF_NAT=y
-CONFIG_IP_NF_MANGLE=y
-CONFIG_IP_NF_TARGET_MASQUERADE=y
-CONFIG_IP_NF_TARGET_NETMAP=y
-CONFIG_IP_NF_TARGET_REDIRECT=y
-CONFIG_IP_NF_RAW=y
-CONFIG_IP_NF_ARPTABLES=y
-CONFIG_IP_NF_ARPFILTER=y
-CONFIG_IP_NF_ARP_MANGLE=y
-CONFIG_IP6_NF_IPTABLES=y
-CONFIG_IP6_NF_TARGET_LOG=y
-CONFIG_IP6_NF_FILTER=y
-CONFIG_IP6_NF_TARGET_REJECT=y
-CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
-CONFIG_IP6_NF_MANGLE=y
-CONFIG_IP6_NF_RAW=y
-CONFIG_PHONET=y
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_HTB=y
-CONFIG_NET_SCH_INGRESS=y
-CONFIG_NET_CLS_U32=y
-CONFIG_NET_EMATCH=y
-CONFIG_NET_EMATCH_U32=y
-CONFIG_NET_CLS_ACT=y
-CONFIG_NET_ACT_POLICE=y
-CONFIG_NET_ACT_GACT=y
-CONFIG_NET_ACT_MIRRED=y
-CONFIG_BT=y
-CONFIG_BT_BNEP=y
-CONFIG_BT_L2CAP=y
-CONFIG_BT_SCO=y
-CONFIG_BT_RFCOMM=y
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_HCIUART=y
-CONFIG_BT_HCIUART_H4=y
-CONFIG_BT_WILINK=y
-CONFIG_RFKILL=y
-CONFIG_RFKILL_INPUT=y
-CONFIG_MTD=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_NAND_IDS=y
-CONFIG_MTD_ONENAND=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_MISC_DEVICES=y
-# CONFIG_ANDROID_PMEM is not set
-CONFIG_KERNEL_DEBUGGER_CORE=y
-CONFIG_UID_STAT=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_MD=y
-CONFIG_BLK_DEV_DM=y
-CONFIG_DM_DEBUG=y
-CONFIG_DM_CRYPT=y
-CONFIG_DM_UEVENT=y
-CONFIG_NETDEVICES=y
-CONFIG_IFB=y
-CONFIG_USB_USBNET=y
-CONFIG_USB_NET_SMSC95XX=y
-CONFIG_PPP=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=y
-CONFIG_PPP_MPPE=y
-CONFIG_PPPOLAC=y
-CONFIG_PPPOPNS=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_KEYRESET=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_KEYCHORD=y
-CONFIG_INPUT_UINPUT=y
-CONFIG_INPUT_GPIO=y
-# CONFIG_VT is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_HW_RANDOM=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_SPI=y
-CONFIG_SPI_GPIO=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_TWL4030=y
-CONFIG_POWER_SUPPLY=y
-# CONFIG_HWMON is not set
-CONFIG_TWL6030_PWM=y
-CONFIG_REGULATOR_TWL4030=y
-CONFIG_MEDIA_SUPPORT=y
-CONFIG_PVR_SGX=y
-CONFIG_PVR_NEED_PVR_DPF=y
-CONFIG_PVR_NEED_PVR_ASSERT=y
-CONFIG_PVR_USSE_EDM_STATUS_DEBUG=y
-CONFIG_FB=y
-CONFIG_OMAP2_DSS=y
-# CONFIG_OMAP2_DSS_VENC is not set
-CONFIG_FB_OMAP2=y
-CONFIG_FB_OMAP2_NUM_FBS=2
-CONFIG_OMAP2_VRAM_SIZE=16
-CONFIG_PANEL_GENERIC_DPI=y
-CONFIG_DISPLAY_SUPPORT=y
-CONFIG_USB=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_SUSPEND=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_MUSB_HDRC=y
-CONFIG_USB_MUSB_OMAP2PLUS=y
-CONFIG_USB_MUSB_PERIPHERAL=y
-CONFIG_USB_GADGET_MUSB_HDRC=y
-CONFIG_USB_ACM=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SERIAL=y
-CONFIG_USB_SERIAL_KEYSPAN=y
-CONFIG_USB_SERIAL_KEYSPAN_MPR=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19=y
-CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_VBUS_DRAW=500
-CONFIG_USB_G_ANDROID=y
-CONFIG_MMC=y
-CONFIG_MMC_UNSAFE_RESUME=y
-CONFIG_MMC_EMBEDDED_SDIO=y
-CONFIG_MMC_PARANOID_SD_INIT=y
-CONFIG_MMC_OMAP=y
-CONFIG_MMC_OMAP_HS=y
-CONFIG_SWITCH=y
-CONFIG_SWITCH_GPIO=y
-CONFIG_RTC_CLASS=y
-CONFIG_STAGING=y
-CONFIG_ANDROID=y
-CONFIG_ANDROID_BINDER_IPC=y
-CONFIG_ANDROID_LOGGER=y
-CONFIG_ANDROID_RAM_CONSOLE=y
-CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION=y
-CONFIG_ANDROID_TIMED_GPIO=y
-CONFIG_ANDROID_LOW_MEMORY_KILLER=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT4_FS=y
-# CONFIG_EXT4_FS_XATTR is not set
-# CONFIG_DNOTIFY is not set
-CONFIG_FUSE_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-# CONFIG_NETWORK_FILESYSTEMS is not set
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_EFI_PARTITION=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_PRINTK_TIME=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_DEBUG_PREEMPT is not set
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-# CONFIG_ARM_UNWIND is not set
-CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRC_CCITT=y
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_SOC=y
-CONFIG_SND_OMAP_SOC=y
-CONFIG_SND_OMAP_SOC_SDP4430=y
-CONFIG_SND_OMAP_SOC_OMAP4_HDMI=y
-CONFIG_OMAP_HSI=y
-CONFIG_OMAP_HSI_DEVICE=y
-CONFIG_CFG80211=y
-CONFIG_NL80211_TESTMODE=y
-CONFIG_LIB80211=y
-CONFIG_MAC80211=y
-CONFIG_MAC80211_LEDS=y
-CONFIG_MAC80211_DEBUGFS=y
-CONFIG_USB_ZD1201=y
-CONFIG_WL12XX_MENU=y
-CONFIG_WL12XX=y
-CONFIG_WL12XX_SDIO=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_OMAP_TEMP_SENSOR=y
-CONFIG_OMAP_DIE_TEMP_SENSOR=y
-CONFIG_TI_ST=y
-CONFIG_KEYBOARD_GPIO=y
diff --git a/kernel/arch/arm/mach-omap2/board-omap3beagle.c b/kernel/arch/arm/mach-omap2/board-omap3beagle.c
deleted file mode 100644
index b3d1b81b2a2e..000000000000
--- a/kernel/arch/arm/mach-omap2/board-omap3beagle.c
+++ /dev/null
@@ -1,1038 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/board-omap3beagle.c
- *
- * Copyright (C) 2008 Texas Instruments
- *
- * Modified from mach-omap2/board-3430sdp.c
- *
- * Initial code: Syed Mohammed Khasim
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/leds.h>
-#include <linux/gpio.h>
-#include <linux/input.h>
-#include <linux/gpio_keys.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/nand.h>
-#include <linux/mmc/host.h>
-
-#include <linux/usb/android_composite.h>
-
-#include <linux/regulator/machine.h>
-#include <linux/i2c/twl.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/flash.h>
-
-#include <plat/board.h>
-#include <plat/common.h>
-#include <plat/display.h>
-#include <plat/gpmc.h>
-#include <plat/nand.h>
-#include <plat/usb.h>
-
-#include "mux.h"
-#include "hsmmc.h"
-#include "timer-gp.h"
-#include "board-flash.h"
-
-#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4
-#include <linux/input/synaptics_dsx.h>
-
-#define TM_SAMPLE1 (1) // 2D only
-#define TM_SAMPLE2 (2) // 2D + 0D x 2
-#define TM_SAMPLE3 (3) // 2D + 0D x 4
-#define SYNAPTICS_MODULE TM_SAMPLE1
-#endif
-
-#define NAND_BLOCK_SIZE SZ_128K
-
-#ifdef CONFIG_USB_ANDROID
-#define GOOGLE_VENDOR_ID 0x18d1
-#define GOOGLE_PRODUCT_ID 0x9018
-#define GOOGLE_ADB_PRODUCT_ID 0x9015
-#endif
-
-/* Synaptics Thin Driver */
-#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4
-static int synaptics_gpio_setup(unsigned gpio, bool configure)
-{
- int retval=0;
- if (configure)
- {
- retval = gpio_request(gpio, "rmi4_attn");
- if (retval) {
- pr_err("%s: Failed to get attn gpio %d. Code: %d.",
- __func__, gpio, retval);
- return retval;
- }
- omap_mux_init_signal("sdmmc2_clk.gpio_130", OMAP_PIN_INPUT_PULLUP);
-
- retval = gpio_direction_input(gpio);
- if (retval) {
- pr_err("%s: Failed to setup attn gpio %d. Code: %d.",
- __func__, gpio, retval);
- gpio_free(gpio);
- }
- } else {
- pr_warn("%s: No way to deconfigure gpio %d.",
- __func__, gpio);
- }
-
- return retval;
-}
-
- #if (SYNAPTICS_MODULE == TM_SAMPLE1)
-#define TM_SAMPLE1_ADDR 0x20
-#define TM_SAMPLE1_ATTN 130
-
-static unsigned char TM_SAMPLE1_f1a_button_codes[] = {};
-
-static struct synaptics_rmi4_capacitance_button_map TM_SAMPLE1_capacitance_button_map = {
- .nbuttons = ARRAY_SIZE(TM_SAMPLE1_f1a_button_codes),
- .map = TM_SAMPLE1_f1a_button_codes,
-};
-
-static struct synaptics_rmi4_platform_data rmi4_platformdata = {
- .irq_flags = IRQF_TRIGGER_FALLING,
- .irq_gpio = TM_SAMPLE1_ATTN,
- .gpio_config = synaptics_gpio_setup,
- .capacitance_button_map = &TM_SAMPLE1_capacitance_button_map,
-};
-
-static struct i2c_board_info bus2_i2c_devices[] = {
- {
- I2C_BOARD_INFO("synaptics_rmi4_i2c", TM_SAMPLE1_ADDR),
- .platform_data = &rmi4_platformdata,
- },
-};
-
-#elif (SYNAPTICS_MODULE == TM_SAMPLE2)
-#define TM_SAMPLE2_ADDR 0x20
-#define TM_SAMPLE2_ATTN 130
-
-static unsigned char TM_SAMPLE2_f1a_button_codes[] = {KEY_MENU, KEY_BACK};
-
-static struct synaptics_rmi4_capacitance_button_map TM_SAMPLE2_capacitance_button_map = {
- .nbuttons = ARRAY_SIZE(TM_SAMPLE2_f1a_button_codes),
- .map = TM_SAMPLE2_f1a_button_codes,
-};
-
-static struct synaptics_rmi4_platform_data rmi4_platformdata = {
- .irq_flags = IRQF_TRIGGER_FALLING,
- .irq_gpio = TM_SAMPLE2_ATTN,
- .gpio_config = synaptics_gpio_setup,
- .capacitance_button_map = &TM_SAMPLE2_capacitance_button_map,
-};
-
-static struct i2c_board_info bus2_i2c_devices[] = {
- {
- I2C_BOARD_INFO("synaptics_rmi4_i2c", TM_SAMPLE2_ADDR),
- .platform_data = &rmi4_platformdata,
- },
-};
-
-#elif (SYNAPTICS_MODULE == TM_SAMPLE3)
-#define TM_SAMPLE3_ADDR 0x20
-#define TM_SAMPLE3_ATTN 130
-
-static unsigned char TM_SAMPLE3_f1a_button_codes[] = {KEY_MENU, KEY_HOME,KEY_BACK,KEY_SEARCH};
-
-static struct synaptics_rmi4_capacitance_button_map TM_SAMPLE3_capacitance_button_map = {
- .nbuttons = ARRAY_SIZE(TM_SAMPLE3_f1a_button_codes),
- .map = TM_SAMPLE3_f1a_button_codes,
-};
-
-static struct synaptics_rmi4_platform_data rmi4_platformdata = {
- .irq_flags = IRQF_TRIGGER_FALLING,
- .irq_gpio = TM_SAMPLE3_ATTN,
- .gpio_config = synaptics_gpio_setup,
- .capacitance_button_map = &TM_SAMPLE3_capacitance_button_map,
-};
-
-static struct i2c_board_info bus2_i2c_devices[] = {
- {
- I2C_BOARD_INFO("synaptics_rmi4_i2c", TM_SAMPLE3_ADDR),
- .platform_data = &rmi4_platformdata,
- },
-};
-#endif
-
-void __init i2c_device_setup(void)
-{
- pr_info(">>>>I2C device setup.");
- if (ARRAY_SIZE(bus2_i2c_devices)) {
- i2c_register_board_info(2, bus2_i2c_devices,
- ARRAY_SIZE(bus2_i2c_devices));
- }
-}
-
-/* End of Synaptics change for beagle board */
-
-static char *usb_functions_adb[] = {
- "adb",
-};
-
-static char *usb_functions_mass_storage[] = {
- "usb_mass_storage",
-};
-static char *usb_functions_ums_adb[] = {
- "usb_mass_storage",
- "adb",
-};
-
-static char *usb_functions_all[] = {
- "adb", "usb_mass_storage",
-};
-
-static struct android_usb_product usb_products[] = {
- {
- .product_id = GOOGLE_PRODUCT_ID,
- .num_functions = ARRAY_SIZE(usb_functions_adb),
- .functions = usb_functions_adb,
- },
- {
- .product_id = GOOGLE_PRODUCT_ID,
- .num_functions = ARRAY_SIZE(usb_functions_mass_storage),
- .functions = usb_functions_mass_storage,
- },
- {
- .product_id = GOOGLE_PRODUCT_ID,
- .num_functions = ARRAY_SIZE(usb_functions_ums_adb),
- .functions = usb_functions_ums_adb,
- },
-};
-
-static struct usb_mass_storage_platform_data mass_storage_pdata = {
- .nluns = 1,
- .vendor = "rowboat",
- .product = "rowboat gadget",
- .release = 0x100,
-};
-
-static struct platform_device usb_mass_storage_device = {
- .name = "usb_mass_storage",
- .id = -1,
- .dev = {
- .platform_data = &mass_storage_pdata,
- },
-};
-
-static struct android_usb_platform_data android_usb_pdata = {
- .vendor_id = GOOGLE_VENDOR_ID,
- .product_id = GOOGLE_PRODUCT_ID,
- .functions = usb_functions_all,
- .products = usb_products,
- .num_products = ARRAY_SIZE(usb_products),
- .version = 0x0100,
- .product_name = "rowboat gadget",
- .manufacturer_name = "rowboat",
- .serial_number = "20100720",
- .num_functions = ARRAY_SIZE(usb_functions_all),
-};
-
-static struct platform_device androidusb_device = {
- .name = "android_usb",
- .id = -1,
- .dev = {
- .platform_data = &android_usb_pdata,
- },
-};
-
-static void omap3beagle_android_gadget_init(void)
-{
- platform_device_register(&androidusb_device);
-}
-#endif
-/*
- * OMAP3 Beagle revision
- * Run time detection of Beagle revision is done by reading GPIO.
- * GPIO ID -
- * AXBX = GPIO173, GPIO172, GPIO171: 1 1 1
- * C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0
- * C4 = GPIO173, GPIO172, GPIO171: 1 0 1
- * XM = GPIO173, GPIO172, GPIO171: 0 0 0
- */
-enum {
- OMAP3BEAGLE_BOARD_UNKN = 0,
- OMAP3BEAGLE_BOARD_AXBX,
- OMAP3BEAGLE_BOARD_C1_3,
- OMAP3BEAGLE_BOARD_C4,
- OMAP3BEAGLE_BOARD_XM,
- OMAP3BEAGLE_BOARD_XMC,
-};
-
-extern void omap_pm_sys_offmode_select(int);
-extern void omap_pm_sys_offmode_pol(int);
-extern void omap_pm_sys_clkreq_pol(int);
-extern void omap_pm_auto_off(int);
-extern void omap_pm_auto_ret(int);
-
-static u8 omap3_beagle_version;
-
-static u8 omap3_beagle_get_rev(void)
-{
- return omap3_beagle_version;
-}
-
-/**
- * Board specific initialization of PM components
- */
-static void __init omap3_beagle_pm_init(void)
-{
- /* Use sys_offmode signal */
- omap_pm_sys_offmode_select(1);
-
- /* sys_clkreq - active high */
- omap_pm_sys_clkreq_pol(1);
-
- /* sys_offmode - active low */
- omap_pm_sys_offmode_pol(0);
-
- /* Automatically send OFF command */
- omap_pm_auto_off(1);
-
- /* Automatically send RET command */
- omap_pm_auto_ret(1);
-}
-
-static void __init omap3_beagle_init_rev(void)
-{
- int ret;
- u16 beagle_rev = 0;
-
- omap_mux_init_gpio(171, OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_gpio(172, OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_gpio(173, OMAP_PIN_INPUT_PULLUP);
-
- ret = gpio_request(171, "rev_id_0");
- if (ret < 0)
- goto fail0;
-
- ret = gpio_request(172, "rev_id_1");
- if (ret < 0)
- goto fail1;
-
- ret = gpio_request(173, "rev_id_2");
- if (ret < 0)
- goto fail2;
-
- gpio_direction_input(171);
- gpio_direction_input(172);
- gpio_direction_input(173);
-
- beagle_rev = gpio_get_value(171) | (gpio_get_value(172) << 1)
- | (gpio_get_value(173) << 2);
-
- switch (beagle_rev) {
- case 7:
- printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n");
- omap3_beagle_version = OMAP3BEAGLE_BOARD_AXBX;
- break;
- case 6:
- printk(KERN_INFO "OMAP3 Beagle Rev: C1/C2/C3\n");
- omap3_beagle_version = OMAP3BEAGLE_BOARD_C1_3;
- break;
- case 5:
- printk(KERN_INFO "OMAP3 Beagle Rev: C4\n");
- omap3_beagle_version = OMAP3BEAGLE_BOARD_C4;
- break;
- case 2:
- printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n");
- omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
- break;
- case 0:
- printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
- omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
- break;
- default:
- printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
- }
-
- return;
-
-fail2:
- gpio_free(172);
-fail1:
- gpio_free(171);
-fail0:
- printk(KERN_ERR "Unable to get revision detection GPIO pins\n");
- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
-
- return;
-}
-
-static struct mtd_partition omap3beagle_nand_partitions[] = {
- /* All the partition sizes are listed in terms of NAND block size */
- {
- .name = "X-Loader",
- .offset = 0,
- .size = 4 * NAND_BLOCK_SIZE,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
- .name = "U-Boot",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
- .size = 15 * NAND_BLOCK_SIZE,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
- .name = "U-Boot Env",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
- .size = 1 * NAND_BLOCK_SIZE,
- },
- {
- .name = "Kernel",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
- .size = 32 * NAND_BLOCK_SIZE,
- },
- {
- .name = "File System",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
- .size = MTDPART_SIZ_FULL,
- },
-};
-
-/* DSS */
-
-static int beagle_enable_dvi(struct omap_dss_device *dssdev)
-{
- if (gpio_is_valid(dssdev->reset_gpio))
- gpio_set_value(dssdev->reset_gpio, 1);
-
- return 0;
-}
-
-static void beagle_disable_dvi(struct omap_dss_device *dssdev)
-{
- if (gpio_is_valid(dssdev->reset_gpio))
- gpio_set_value(dssdev->reset_gpio, 0);
-}
-
-static struct omap_dss_device beagle_dvi_device = {
- .type = OMAP_DISPLAY_TYPE_DPI,
- .name = "dvi",
- .driver_name = "generic_panel",
- .phy.dpi.data_lines = 24,
- .reset_gpio = -EINVAL,
- .platform_enable = beagle_enable_dvi,
- .platform_disable = beagle_disable_dvi,
-};
-
-static struct omap_dss_device beagle_tv_device = {
- .name = "tv",
- .driver_name = "venc",
- .type = OMAP_DISPLAY_TYPE_VENC,
- .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
-};
-
-static struct omap_dss_device *beagle_dss_devices[] = {
- &beagle_dvi_device,
- &beagle_tv_device,
-};
-
-static struct omap_dss_board_info beagle_dss_data = {
- .num_devices = ARRAY_SIZE(beagle_dss_devices),
- .devices = beagle_dss_devices,
- .default_device = &beagle_dvi_device,
-};
-
-static struct platform_device beagle_dss_device = {
- .name = "omapdss",
- .id = -1,
- .dev = {
- .platform_data = &beagle_dss_data,
- },
-};
-
-static struct regulator_consumer_supply beagle_vdac_supply =
- REGULATOR_SUPPLY("vdda_dac", "omapdss");
-
-static struct regulator_consumer_supply beagle_vdvi_supply =
- REGULATOR_SUPPLY("vdds_dsi", "omapdss");
-
-static void __init beagle_display_init(void)
-{
- int r;
-
- r = gpio_request(beagle_dvi_device.reset_gpio, "DVI reset");
- if (r < 0) {
- printk(KERN_ERR "Unable to get DVI reset GPIO\n");
- return;
- }
-
- gpio_direction_output(beagle_dvi_device.reset_gpio, 0);
-}
-
-#include "sdram-micron-mt46h32m32lf-6.h"
-
-static struct omap2_hsmmc_info mmc[] = {
- {
- .mmc = 1,
- .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
- .gpio_wp = 29,
- },
- {} /* Terminator */
-};
-
-static struct regulator_consumer_supply beagle_vmmc1_supply = {
- .supply = "vmmc",
-};
-
-static struct regulator_consumer_supply beagle_vsim_supply = {
- .supply = "vmmc_aux",
-};
-
-static struct regulator_consumer_supply beagle_vaux3_supply = {
- .supply = "cam_1v8",
-};
-
-static struct regulator_consumer_supply beagle_vaux4_supply = {
- .supply = "cam_2v8",
-};
-
-static struct gpio_led gpio_leds[];
-
-static int beagle_twl_gpio_setup(struct device *dev,
- unsigned gpio, unsigned ngpio)
-{
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
- mmc[0].gpio_wp = -EINVAL;
- } else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
- (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
- omap_mux_init_gpio(23, OMAP_PIN_INPUT);
- mmc[0].gpio_wp = 23;
- } else {
- omap_mux_init_gpio(29, OMAP_PIN_INPUT);
- }
- /* gpio + 0 is "mmc0_cd" (input/IRQ) */
- mmc[0].gpio_cd = gpio + 0;
- omap2_hsmmc_init(mmc);
-
- /* link regulators to MMC adapters */
- beagle_vmmc1_supply.dev = mmc[0].dev;
- beagle_vsim_supply.dev = mmc[0].dev;
-
- /* REVISIT: need ehci-omap hooks for external VBUS
- * power switch and overcurrent detect
- */
- if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
- gpio_request(gpio + 1, "EHCI_nOC");
- gpio_direction_input(gpio + 1);
- }
-
- /*
- * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active
- * high / others active low)
- */
- gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
- else
- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
-
- /* DVI reset GPIO is different between beagle revisions */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC)
- beagle_dvi_device.reset_gpio = 129;
- else
- beagle_dvi_device.reset_gpio = 170;
-
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
- /* Power on camera interface */
- gpio_request(gpio + 2, "CAM_EN");
- gpio_direction_output(gpio + 2, 1);
-
- /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
- gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
- } else {
- gpio_request(gpio + 1, "EHCI_nOC");
- gpio_direction_input(gpio + 1);
-
- /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
- gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
- }
- /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
- gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
-
- /*
- * gpio + 1 on Xm controls the TFP410's enable line (active low)
- * gpio + 2 control varies depending on the board rev as follows:
- * P7/P8 revisions(prototype): Camera EN
- * A2+ revisions (production): LDO (supplies DVI, serial, led blocks)
- */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
- gpio_request(gpio + 1, "nDVI_PWR_EN");
- gpio_direction_output(gpio + 1, 0);
- gpio_request(gpio + 2, "DVI_LDO_EN");
- gpio_direction_output(gpio + 2, 1);
- }
-
- return 0;
-}
-
-static struct twl4030_gpio_platform_data beagle_gpio_data = {
- .gpio_base = OMAP_MAX_GPIO_LINES,
- .irq_base = TWL4030_GPIO_IRQ_BASE,
- .irq_end = TWL4030_GPIO_IRQ_END,
- .use_leds = true,
- .pullups = BIT(1),
- .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
- | BIT(15) | BIT(16) | BIT(17),
- .setup = beagle_twl_gpio_setup,
-};
-
-/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
-static struct regulator_init_data beagle_vmmc1 = {
- .constraints = {
- .min_uV = 1850000,
- .max_uV = 3150000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &beagle_vmmc1_supply,
-};
-
-/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
-static struct regulator_init_data beagle_vsim = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 3000000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &beagle_vsim_supply,
-};
-
-/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
-static struct regulator_init_data beagle_vdac = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &beagle_vdac_supply,
-};
-
-/* VPLL2 for digital video outputs */
-static struct regulator_init_data beagle_vpll2 = {
- .constraints = {
- .name = "VDVI",
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &beagle_vdvi_supply,
-};
-
-/* VAUX3 for CAM_1V8 */
-static struct regulator_init_data beagle_vaux3 = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &beagle_vaux3_supply,
-};
-
- /* VAUX4 for CAM_2V8 */
-static struct regulator_init_data beagle_vaux4 = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &beagle_vaux4_supply,
-};
-
-static struct twl4030_usb_data beagle_usb_data = {
- .usb_mode = T2_USB_MODE_ULPI,
-};
-
-/**
- * Macro to configure resources
- */
-#define TWL4030_RESCONFIG(res,grp,typ1,typ2,state) \
- { \
- .resource = res, \
- .devgroup = grp, \
- .type = typ1, \
- .type2 = typ2, \
- .remap_sleep = state \
- }
-
-static struct twl4030_resconfig __initdata board_twl4030_rconfig[] = {
- TWL4030_RESCONFIG(RES_VPLL1, DEV_GRP_P1, 3, 1, RES_STATE_OFF), /* ? */
- TWL4030_RESCONFIG(RES_VINTANA1, DEV_GRP_ALL, 1, 2, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_VINTANA2, DEV_GRP_ALL, 0, 2, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_VINTDIG, DEV_GRP_ALL, 1, 2, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_VIO, DEV_GRP_ALL, 2, 2, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_VDD1, DEV_GRP_P1, 4, 1, RES_STATE_OFF), /* ? */
- TWL4030_RESCONFIG(RES_VDD2, DEV_GRP_P1, 3, 1, RES_STATE_OFF), /* ? */
- TWL4030_RESCONFIG(RES_REGEN, DEV_GRP_ALL, 2, 1, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_NRES_PWRON, DEV_GRP_ALL, 0, 1, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_CLKEN, DEV_GRP_ALL, 3, 2, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_SYSEN, DEV_GRP_ALL, 6, 1, RES_STATE_SLEEP),
- TWL4030_RESCONFIG(RES_HFCLKOUT, DEV_GRP_P3, 0, 2, RES_STATE_SLEEP), /* ? */
- TWL4030_RESCONFIG(0, 0, 0, 0, 0),
-};
-
-/**
- * Optimized 'Active to Sleep' sequence
- */
-static struct twl4030_ins omap3beagle_sleep_seq[] __initdata = {
- { MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_SLEEP), 20},
- { MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1, RES_STATE_SLEEP), 2 },
- { MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2, RES_STATE_SLEEP), 2 },
-};
-
-static struct twl4030_script omap3beagle_sleep_script __initdata = {
- .script = omap3beagle_sleep_seq,
- .size = ARRAY_SIZE(omap3beagle_sleep_seq),
- .flags = TWL4030_SLEEP_SCRIPT,
-};
-
-/**
- * Optimized 'Sleep to Active (P12)' sequence
- */
-static struct twl4030_ins omap3beagle_wake_p12_seq[] __initdata = {
- { MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1, RES_STATE_ACTIVE), 2 }
-};
-
-static struct twl4030_script omap3beagle_wake_p12_script __initdata = {
- .script = omap3beagle_wake_p12_seq,
- .size = ARRAY_SIZE(omap3beagle_wake_p12_seq),
- .flags = TWL4030_WAKEUP12_SCRIPT,
-};
-
-/**
- * Optimized 'Sleep to Active' (P3) sequence
- */
-static struct twl4030_ins omap3beagle_wake_p3_seq[] __initdata = {
- { MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2, RES_STATE_ACTIVE), 2 }
-};
-
-static struct twl4030_script omap3beagle_wake_p3_script __initdata = {
- .script = omap3beagle_wake_p3_seq,
- .size = ARRAY_SIZE(omap3beagle_wake_p3_seq),
- .flags = TWL4030_WAKEUP3_SCRIPT,
-};
-
-/**
- * Optimized warm reset sequence (for less power surge)
- */
-static struct twl4030_ins omap3beagle_wrst_seq[] __initdata = {
- { MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_OFF), 0x2 },
- { MSG_SINGULAR(DEV_GRP_NULL, RES_MAIN_REF, RES_STATE_WRST), 2 },
- { MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2, RES_STATE_WRST), 0x2},
- { MSG_SINGULAR(DEV_GRP_NULL, RES_VUSB_3V1, RES_STATE_WRST), 0x2 },
- { MSG_SINGULAR(DEV_GRP_NULL, RES_VPLL1, RES_STATE_WRST), 0x2 },
- { MSG_SINGULAR(DEV_GRP_NULL, RES_VDD2, RES_STATE_WRST), 0x7 },
- { MSG_SINGULAR(DEV_GRP_NULL, RES_VDD1, RES_STATE_WRST), 0x25 },
- { MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0, RES_STATE_WRST), 0x2 },
- { MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_ACTIVE), 0x2 },
-
-};
-
-static struct twl4030_script omap3beagle_wrst_script __initdata = {
- .script = omap3beagle_wrst_seq,
- .size = ARRAY_SIZE(omap3beagle_wrst_seq),
- .flags = TWL4030_WRST_SCRIPT,
-};
-
-static struct twl4030_script __initdata *board_twl4030_scripts[] = {
- &omap3beagle_wake_p12_script,
- &omap3beagle_wake_p3_script,
- &omap3beagle_sleep_script,
- &omap3beagle_wrst_script
-};
-
-static struct twl4030_power_data __initdata omap3beagle_script_data = {
- .scripts = board_twl4030_scripts,
- .num = ARRAY_SIZE(board_twl4030_scripts),
- .resource_config = board_twl4030_rconfig,
-};
-
-static struct twl4030_codec_audio_data beagle_audio_data = {
- .audio_mclk = 26000000,
- .digimic_delay = 1,
- .ramp_delay_value = 1,
- .offset_cncl_path = 1,
- .check_defaults = false,
- .reset_registers = false,
- .reset_registers = false,
-};
-
-static struct twl4030_codec_data beagle_codec_data = {
- .audio_mclk = 26000000,
- .audio = &beagle_audio_data,
-};
-
-static struct twl4030_platform_data beagle_twldata = {
- .irq_base = TWL4030_IRQ_BASE,
- .irq_end = TWL4030_IRQ_END,
-
- /* platform_data for children goes here */
- .usb = &beagle_usb_data,
- .gpio = &beagle_gpio_data,
- .codec = &beagle_codec_data,
- .vmmc1 = &beagle_vmmc1,
- .vsim = &beagle_vsim,
- .vdac = &beagle_vdac,
- .vpll2 = &beagle_vpll2,
- .vaux3 = &beagle_vaux3,
- .vaux4 = &beagle_vaux4,
- .power = &omap3beagle_script_data,
-};
-
-static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
- {
- I2C_BOARD_INFO("twl4030", 0x48),
- .flags = I2C_CLIENT_WAKE,
- .irq = INT_34XX_SYS_NIRQ,
- .platform_data = &beagle_twldata,
- },
-};
-
-static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
- {
- I2C_BOARD_INFO("eeprom", 0x50),
- },
-};
-
-static int __init omap3_beagle_i2c_init(void)
-{
- omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo,
- ARRAY_SIZE(beagle_i2c_boardinfo));
-
- /* Bus 2 is used for Camera/Sensor interface */
- if (ARRAY_SIZE(bus2_i2c_devices))
- omap_register_i2c_bus(2, 400, bus2_i2c_devices,
- ARRAY_SIZE(bus2_i2c_devices));
- else
- omap_register_i2c_bus(2, 400, NULL, 0);
-
- /* Bus 3 is attached to the DVI port where devices like the pico DLP
- * projector don't work reliably with 400kHz */
- omap_register_i2c_bus(3, 100, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom));
-
- return 0;
-}
-
-static struct gpio_led gpio_leds[] = {
- {
- .name = "beagleboard::usr0",
- .default_trigger = "heartbeat",
- .gpio = 150,
- },
- {
- .name = "beagleboard::usr1",
- .default_trigger = "mmc0",
- .gpio = 149,
- },
- {
- .name = "beagleboard::pmu_stat",
- .gpio = -EINVAL, /* gets replaced */
- .active_low = true,
- },
-};
-
-static struct gpio_led_platform_data gpio_led_info = {
- .leds = gpio_leds,
- .num_leds = ARRAY_SIZE(gpio_leds),
-};
-
-static struct platform_device leds_gpio = {
- .name = "leds-gpio",
- .id = -1,
- .dev = {
- .platform_data = &gpio_led_info,
- },
-};
-
-static struct gpio_keys_button gpio_buttons[] = {
- {
- .code = KEY_POWER,
- .gpio = 4,
- .desc = "user",
- .wakeup = 1,
- },
-};
-
-static struct gpio_keys_platform_data gpio_key_info = {
- .buttons = gpio_buttons,
- .nbuttons = ARRAY_SIZE(gpio_buttons),
-};
-
-static struct platform_device keys_gpio = {
- .name = "gpio-keys",
- .id = -1,
- .dev = {
- .platform_data = &gpio_key_info,
- },
-};
-
-static void __init omap3_beagle_init_irq(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
- mt46h32m32lf6_sdrc_params);
- omap_init_irq();
- gpmc_init();
-#ifdef CONFIG_OMAP_32K_TIMER
- if (omap3_beagle_version == OMAP3BEAGLE_BOARD_AXBX)
- omap2_gp_clockevent_set_gptimer(12);
- else
- omap2_gp_clockevent_set_gptimer(1);
-#endif
-}
-
-static struct platform_device *omap3_beagle_devices[] __initdata = {
- &leds_gpio,
- &keys_gpio,
- &beagle_dss_device,
- &usb_mass_storage_device,
-};
-
-static void __init omap3beagle_flash_init(void)
-{
- u8 cs = 0;
- u8 nandcs = GPMC_CS_NUM + 1;
-
- /* find out the chip-select on which NAND exists */
- while (cs < GPMC_CS_NUM) {
- u32 ret = 0;
- ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
-
- if ((ret & 0xC00) == 0x800) {
- printk(KERN_INFO "Found NAND on CS%d\n", cs);
- if (nandcs > GPMC_CS_NUM)
- nandcs = cs;
- }
- cs++;
- }
-
- if (nandcs > GPMC_CS_NUM) {
- printk(KERN_INFO "NAND: Unable to find configuration "
- "in GPMC\n ");
- return;
- }
-
- if (nandcs < GPMC_CS_NUM) {
- printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
- board_nand_init(omap3beagle_nand_partitions,
- ARRAY_SIZE(omap3beagle_nand_partitions),
- nandcs, NAND_BUSWIDTH_16);
- }
-}
-
-static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
-
- .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
- .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
- .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
-
- .phy_reset = true,
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = 147,
- .reset_gpio_port[2] = -EINVAL
-};
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
- OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
- OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW |
- OMAP_PIN_OFF_WAKEUPENABLE),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#endif
-
-static struct omap_musb_board_data musb_board_data = {
- .interface_type = MUSB_INTERFACE_ULPI,
- .mode = MUSB_OTG,
- .power = 100,
-};
-
-static void __init omap3_beagle_init(void)
-{
- omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
- omap3_beagle_init_rev();
- omap3_beagle_i2c_init();
- platform_add_devices(omap3_beagle_devices,
- ARRAY_SIZE(omap3_beagle_devices));
- omap_serial_init();
-
- omap_mux_init_gpio(170, OMAP_PIN_INPUT);
- gpio_request(170, "DVI_nPD");
- /* REVISIT leave DVI powered down until it's needed ... */
- gpio_direction_output(170, true);
-
- usb_musb_init(&musb_board_data);
- usb_ehci_init(&ehci_pdata);
- omap3beagle_flash_init();
-
- /* Ensure SDRC pins are mux'd for self-refresh */
- omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
- omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
-
- beagle_display_init();
-#ifdef CONFIG_USB_ANDROID
- omap3beagle_android_gadget_init();
-#endif
- omap3_beagle_pm_init();
-}
-
-MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
- /* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
- .boot_params = 0x80000100,
- .map_io = omap3_map_io,
- .reserve = omap_reserve,
- .init_irq = omap3_beagle_init_irq,
- .init_machine = omap3_beagle_init,
- .timer = &omap_timer,
-MACHINE_END
diff --git a/kernel/arch/arm/mach-omap2/board-omap4panda.c b/kernel/arch/arm/mach-omap2/board-omap4panda.c
deleted file mode 100644
index 4f8c79ddd650..000000000000
--- a/kernel/arch/arm/mach-omap2/board-omap4panda.c
+++ /dev/null
@@ -1,1053 +0,0 @@
-/*
- * Board support file for OMAP4430 based PandaBoard.
- *
- * Copyright (C) 2010 Texas Instruments
- *
- * Author: David Anders <x0132446@ti.com>
- *
- * Based on mach-omap2/board-4430sdp.c
- *
- * Author: Santosh Shilimkar <santosh.shilimkar@ti.com>
- *
- * Based on mach-omap2/board-3430sdp.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/input.h>
-#include <linux/io.h>
-#include <linux/leds.h>
-#include <linux/gpio.h>
-#include <linux/gpio_keys.h>
-#include <linux/omapfb.h>
-#include <linux/reboot.h>
-#include <linux/usb/otg.h>
-#include <linux/i2c/twl.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/wl12xx.h>
-#include <linux/memblock.h>
-#include <linux/skbuff.h>
-#include <linux/ti_wilink_st.h>
-#include <linux/platform_data/ram_console.h>
-
-#include <mach/hardware.h>
-#include <mach/omap4-common.h>
-#include <mach/emif.h>
-#include <mach/lpddr2-elpida.h>
-#include <mach/dmm.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <video/omapdss.h>
-
-#include <plat/board.h>
-#include <plat/common.h>
-#include <plat/usb.h>
-#include <plat/mmc.h>
-#include <plat/remoteproc.h>
-#include <plat/vram.h>
-#include <video/omap-panel-generic-dpi.h>
-#include "timer-gp.h"
-
-#include "hsmmc.h"
-#include "control.h"
-#include "mux.h"
-#include "common-board-devices.h"
-#include "prm-regbits-44xx.h"
-#include "prm44xx.h"
-#include "pm.h"
-#include "resetreason.h"
-
-#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4
-#include <linux/input/synaptics_dsx.h>
-#define TM_SAMPLE1 (1) // 2D only
-#define TM_SAMPLE2 (2) // 2D + 0D x 2
-#define TM_SAMPLE3 (3) // 2D + 0D x 4
-#define SYNAPTICS_MODULE TM_SAMPLE1
-#endif
-
-#define PANDA_RAMCONSOLE_START (PLAT_PHYS_OFFSET + SZ_512M)
-#define PANDA_RAMCONSOLE_SIZE SZ_2M
-
-#define GPIO_HUB_POWER 1
-#define GPIO_HUB_NRESET 62
-#define GPIO_WIFI_PMENA 43
-#define GPIO_WIFI_IRQ 53
-#define HDMI_GPIO_CT_CP_HPD 60
-#define HDMI_GPIO_HPD 63 /* Hot plug pin for HDMI */
-#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
-#define TPS62361_GPIO 7 /* VCORE1 power control */
-#define PANDA_BT_GPIO 46
-
-
-#define PHYS_ADDR_SMC_SIZE (SZ_1M * 3)
-#define PHYS_ADDR_SMC_MEM (0x80000000 + SZ_1G - PHYS_ADDR_SMC_SIZE)
-#define OMAP_ION_HEAP_SECURE_INPUT_SIZE (SZ_1M * 90)
-#define PHYS_ADDR_DUCATI_SIZE (SZ_1M * 105)
-#define PHYS_ADDR_DUCATI_MEM (PHYS_ADDR_SMC_MEM - PHYS_ADDR_DUCATI_SIZE - \
- OMAP_ION_HEAP_SECURE_INPUT_SIZE)
-
-#define WILINK_UART_DEV_NAME "/dev/ttyO1"
-
-
-/* Synaptics changes for PandaBoard */
-#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4
-static int synaptics_gpio_setup(unsigned gpio, bool configure)
-{
- int retval = 0;
-
- if (configure) {
- retval = gpio_request(gpio, "rmi4_attn");
- if (retval) {
- pr_err("%s: Failed to get attn gpio %d (code: %d)",
- __func__, gpio, retval);
- return retval;
- }
- omap_mux_init_signal("gpmc_ad15.gpio_39", OMAP_PIN_INPUT_PULLUP);
-
- retval = gpio_direction_input(gpio);
- if (retval) {
- pr_err("%s: Failed to setup attn gpio %d (code: %d)",
- __func__, gpio, retval);
- gpio_free(gpio);
- }
- } else {
- pr_warn("%s: No way to deconfigure gpio %d",
- __func__, gpio);
- }
-
- return retval;
-}
-
- #if (SYNAPTICS_MODULE == TM_SAMPLE1)
-#define TM_SAMPLE1_ADDR 0x20
-#define TM_SAMPLE1_ATTN 130
-
-static unsigned char TM_SAMPLE1_f1a_button_codes[] = {};
-
-static struct synaptics_rmi4_capacitance_button_map TM_SAMPLE1_capacitance_button_map = {
- .nbuttons = ARRAY_SIZE(TM_SAMPLE1_f1a_button_codes),
- .map = TM_SAMPLE1_f1a_button_codes,
-};
-
-static struct synaptics_rmi4_platform_data rmi4_platformdata = {
- .irq_flags = IRQF_TRIGGER_FALLING,
- .irq_gpio = TM_SAMPLE1_ATTN,
- .gpio_config = synaptics_gpio_setup,
- .capacitance_button_map = &TM_SAMPLE1_capacitance_button_map,
-};
-
-static struct i2c_board_info bus4_i2c_devices[] = {
- {
- I2C_BOARD_INFO("synaptics_rmi4_i2c", TM_SAMPLE1_ADDR),
- .platform_data = &rmi4_platformdata,
- },
-};
-
-#elif (SYNAPTICS_MODULE == TM_SAMPLE2)
-#define TM_SAMPLE2_ADDR 0x20
-#define TM_SAMPLE2_ATTN 130
-
-static unsigned char TM_SAMPLE2_f1a_button_codes[] = {KEY_MENU, KEY_BACK};
-
-static struct synaptics_rmi4_capacitance_button_map TM_SAMPLE2_capacitance_button_map = {
- .nbuttons = ARRAY_SIZE(TM_SAMPLE2_f1a_button_codes),
- .map = TM_SAMPLE2_f1a_button_codes,
-};
-
-static struct synaptics_rmi4_platform_data rmi4_platformdata = {
- .irq_flags = IRQF_TRIGGER_FALLING,
- .irq_gpio = TM_SAMPLE2_ATTN,
- .gpio_config = synaptics_gpio_setup,
- .capacitance_button_map = &TM_SAMPLE2_capacitance_button_map,
-};
-
-static struct i2c_board_info bus4_i2c_devices[] = {
- {
- I2C_BOARD_INFO("synaptics_rmi4_i2c", TM_SAMPLE2_ADDR),
- .platform_data = &rmi4_platformdata,
- },
-};
-};
-
-#elif (SYNAPTICS_MODULE == TM_SAMPLE3)
-#define TM_SAMPLE3_ADDR 0x20
-#define TM_SAMPLE3_ATTN 130
-
-static unsigned char TM_SAMPLE3_f1a_button_codes[] = {KEY_MENU, KEY_HOME,KEY_BACK,KEY_SEARCH};
-
-static struct synaptics_rmi4_capacitance_button_map TM_SAMPLE3_capacitance_button_map = {
- .nbuttons = ARRAY_SIZE(TM_SAMPLE3_f1a_button_codes),
- .map = TM_SAMPLE3_f1a_button_codes,
-};
-
-static struct synaptics_rmi4_platform_data rmi4_platformdata = {
- .irq_flags = IRQF_TRIGGER_FALLING,
- .irq_gpio = TM_SAMPLE3_ATTN,
- .gpio_config = synaptics_gpio_setup,
- .capacitance_button_map = &TM_SAMPLE3_capacitance_button_map,
-};
-
-static struct i2c_board_info bus4_i2c_devices[] = {
- {
- I2C_BOARD_INFO("synaptics_rmi4_i2c", TM_SAMPLE3_ADDR),
- .platform_data = &rmi4_platformdata,
- },
-};
-#endif
-
-void __init i2c_device_setup(void)
-{
- pr_info(">>>>I2C device setup");
- if (ARRAY_SIZE(bus4_i2c_devices)) {
- i2c_register_board_info(4, bus4_i2c_devices,
- ARRAY_SIZE(bus4_i2c_devices));
- }
-}
-#endif
-/* End of Synaptics changes for PandaBoard */
-
-static struct gpio_led gpio_leds[] = {
- {
- .name = "pandaboard::status1",
- .default_trigger = "heartbeat",
- .gpio = 7,
- },
- {
- .name = "pandaboard::status2",
- .default_trigger = "mmc0",
- .gpio = 8,
- },
-};
-
-static struct gpio_led_platform_data gpio_led_info = {
- .leds = gpio_leds,
- .num_leds = ARRAY_SIZE(gpio_leds),
-};
-
-static struct platform_device leds_gpio = {
- .name = "leds-gpio",
- .id = -1,
- .dev = {
- .platform_data = &gpio_led_info,
- },
-};
-
-/* GPIO_KEY for the panda */
-static struct gpio_keys_button panda_gpio_keys_buttons[] = {
- [0] = {
- .code = KEY_HOME,
- .gpio = 113,
- .desc = "user_button",
- .active_low = 1,
- .debounce_interval = 5,
- },
-};
-
-static struct gpio_keys_platform_data panda_gpio_keys = {
- .buttons = panda_gpio_keys_buttons,
- .nbuttons = ARRAY_SIZE(panda_gpio_keys_buttons),
- .rep = 0,
-};
-
-static struct platform_device panda_gpio_keys_device = {
- .name = "gpio-keys",
- .id = -1,
- .dev = {
- .platform_data = &panda_gpio_keys,
- },
-};
-
-/* TODO: handle suspend/resume here.
- * Upon every suspend, make sure the wilink chip is
- * capable enough to wake-up the OMAP host.
- */
-static int plat_wlink_kim_suspend(struct platform_device *pdev, pm_message_t
- state)
-{
- return 0;
-}
-
-static int plat_wlink_kim_resume(struct platform_device *pdev)
-{
- return 0;
-}
-
-/* wl128x BT, FM, GPS connectivity chip */
-static struct ti_st_plat_data wilink_pdata = {
- .nshutdown_gpio = PANDA_BT_GPIO,
- .dev_name = WILINK_UART_DEV_NAME,
- .flow_cntrl = 1,
- .baud_rate = 3686400,
- .suspend = plat_wlink_kim_suspend,
- .resume = plat_wlink_kim_resume,
-};
-
-static struct platform_device btwilink_device = {
- .name = "btwilink",
- .id = -1,
-};
-
-/* wl127x BT, FM, GPS connectivity chip */
-static struct platform_device wl1271_device = {
- .name = "kim",
- .id = -1,
- .dev.platform_data = &wilink_pdata,
-};
-
-
-static struct platform_device *panda_devices[] __initdata = {
- &leds_gpio,
- &wl1271_device,
- &btwilink_device,
- &panda_gpio_keys_device,
-};
-
-static void __init omap4_panda_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(NULL, NULL);
-}
-
-static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
- .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
- .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
- .phy_reset = false,
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = -EINVAL,
- .reset_gpio_port[2] = -EINVAL
-};
-
-static struct gpio panda_ehci_gpios[] __initdata = {
- { GPIO_HUB_POWER, GPIOF_OUT_INIT_LOW, "hub_power" },
- { GPIO_HUB_NRESET, GPIOF_OUT_INIT_LOW, "hub_nreset" },
-};
-
-static void __init omap4_ehci_init(void)
-{
- int ret;
- struct clk *phy_ref_clk;
-
- /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */
- phy_ref_clk = clk_get(NULL, "auxclk3_ck");
- if (IS_ERR(phy_ref_clk)) {
- pr_err("Cannot request auxclk3\n");
- return;
- }
- clk_set_rate(phy_ref_clk, 19200000);
- clk_enable(phy_ref_clk);
-
- /* disable the power to the usb hub prior to init and reset phy+hub */
- ret = gpio_request_array(panda_ehci_gpios,
- ARRAY_SIZE(panda_ehci_gpios));
- if (ret) {
- pr_err("Unable to initialize EHCI power/reset\n");
- return;
- }
-
- gpio_export(GPIO_HUB_POWER, 0);
- gpio_export(GPIO_HUB_NRESET, 0);
- gpio_set_value(GPIO_HUB_NRESET, 1);
-
- usbhs_init(&usbhs_bdata);
-
- /* enable power to hub */
- gpio_set_value(GPIO_HUB_POWER, 1);
-}
-
-static struct omap_musb_board_data musb_board_data = {
- .interface_type = MUSB_INTERFACE_UTMI,
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
- .mode = MUSB_PERIPHERAL,
-#else
- .mode = MUSB_OTG,
-#endif
- .power = 100,
-};
-
-static struct twl4030_usb_data omap4_usbphy_data = {
- .phy_init = omap4430_phy_init,
- .phy_exit = omap4430_phy_exit,
- .phy_power = omap4430_phy_power,
- .phy_set_clock = omap4430_phy_set_clk,
- .phy_suspend = omap4430_phy_suspend,
-};
-
-static struct omap2_hsmmc_info mmc[] = {
- {
- .mmc = 1,
- .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
- .gpio_wp = -EINVAL,
- .gpio_cd = -EINVAL,
- },
- {
- .name = "wl1271",
- .mmc = 5,
- .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
- .gpio_wp = -EINVAL,
- .gpio_cd = -EINVAL,
- .ocr_mask = MMC_VDD_165_195,
- .nonremovable = true,
- },
- {} /* Terminator */
-};
-
-static struct regulator_consumer_supply omap4_panda_vmmc_supply[] = {
- {
- .supply = "vmmc",
- .dev_name = "omap_hsmmc.0",
- },
-};
-
-static struct regulator_consumer_supply omap4_panda_vmmc5_supply = {
- .supply = "vmmc",
- .dev_name = "omap_hsmmc.4",
-};
-
-static struct regulator_init_data panda_vmmc5 = {
- .constraints = {
- .valid_ops_mask = REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &omap4_panda_vmmc5_supply,
-};
-
-static struct fixed_voltage_config panda_vwlan = {
- .supply_name = "vwl1271",
- .microvolts = 1800000, /* 1.8V */
- .gpio = GPIO_WIFI_PMENA,
- .startup_delay = 70000, /* 70msec */
- .enable_high = 1,
- .enabled_at_boot = 0,
- .init_data = &panda_vmmc5,
-};
-
-static struct platform_device omap_vwlan_device = {
- .name = "reg-fixed-voltage",
- .id = 1,
- .dev = {
- .platform_data = &panda_vwlan,
- },
-};
-
-struct wl12xx_platform_data omap_panda_wlan_data __initdata = {
- .irq = OMAP_GPIO_IRQ(GPIO_WIFI_IRQ),
- /* PANDA ref clock is 38.4 MHz */
- .board_ref_clock = 2,
-};
-
-static int omap4_twl6030_hsmmc_late_init(struct device *dev)
-{
- int ret = 0;
- struct platform_device *pdev = container_of(dev,
- struct platform_device, dev);
- struct omap_mmc_platform_data *pdata = dev->platform_data;
-
- if (!pdata) {
- dev_err(dev, "%s: NULL platform data\n", __func__);
- return -EINVAL;
- }
- /* Setting MMC1 Card detect Irq */
- if (pdev->id == 0) {
- ret = twl6030_mmc_card_detect_config();
- if (ret)
- dev_err(dev, "%s: Error card detect config(%d)\n",
- __func__, ret);
- else
- pdata->slots[0].card_detect = twl6030_mmc_card_detect;
- }
- return ret;
-}
-
-static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
-{
- struct omap_mmc_platform_data *pdata;
-
- /* dev can be null if CONFIG_MMC_OMAP_HS is not set */
- if (!dev) {
- pr_err("Failed omap4_twl6030_hsmmc_set_late_init\n");
- return;
- }
- pdata = dev->platform_data;
-
- pdata->init = omap4_twl6030_hsmmc_late_init;
-}
-
-static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
-{
- struct omap2_hsmmc_info *c;
-
- omap2_hsmmc_init(controllers);
- for (c = controllers; c->mmc; c++)
- omap4_twl6030_hsmmc_set_late_init(c->dev);
-
- return 0;
-}
-
-static struct regulator_init_data omap4_panda_vaux2 = {
- .constraints = {
- .min_uV = 1200000,
- .max_uV = 2800000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_init_data omap4_panda_vaux3 = {
- .constraints = {
- .min_uV = 1000000,
- .max_uV = 3000000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-/* VMMC1 for MMC1 card */
-static struct regulator_init_data omap4_panda_vmmc = {
- .constraints = {
- .min_uV = 1200000,
- .max_uV = 3000000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = omap4_panda_vmmc_supply,
-};
-
-static struct regulator_init_data omap4_panda_vpp = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 2500000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_init_data omap4_panda_vana = {
- .constraints = {
- .min_uV = 2100000,
- .max_uV = 2100000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_init_data omap4_panda_vcxio = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_consumer_supply panda_vdac_supply[] = {
- {
- .supply = "hdmi_vref",
- },
-};
-
-static struct regulator_init_data omap4_panda_vdac = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = ARRAY_SIZE(panda_vdac_supply),
- .consumer_supplies = panda_vdac_supply,
-};
-
-static struct regulator_init_data omap4_panda_vusb = {
- .constraints = {
- .min_uV = 3300000,
- .max_uV = 3300000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_init_data omap4_panda_clk32kg = {
- .constraints = {
- .valid_ops_mask = REGULATOR_CHANGE_STATUS,
- .always_on = true,
- },
-};
-
-static void omap4_audio_conf(void)
-{
- /* twl6040 naudint */
- omap_mux_init_signal("sys_nirq2.sys_nirq2", \
- OMAP_PIN_INPUT_PULLUP);
-}
-
-static struct twl4030_codec_audio_data twl6040_audio = {
- /* single-step ramp for headset and handsfree */
- .hs_left_step = 0x0f,
- .hs_right_step = 0x0f,
- .hf_left_step = 0x1d,
- .hf_right_step = 0x1d,
- .hs_switch_dev = 0x1,
- .hs_forced_hs_state = 0x1
-};
-
-static struct twl4030_codec_data twl6040_codec = {
- .audio = &twl6040_audio,
- .audpwron_gpio = 127,
- .naudint_irq = OMAP44XX_IRQ_SYS_2N,
- .irq_base = TWL6040_CODEC_IRQ_BASE,
-};
-
-static struct twl4030_platform_data omap4_panda_twldata = {
- .irq_base = TWL6030_IRQ_BASE,
- .irq_end = TWL6030_IRQ_END,
-
- /* Regulators */
- .vmmc = &omap4_panda_vmmc,
- .vpp = &omap4_panda_vpp,
- .vana = &omap4_panda_vana,
- .vcxio = &omap4_panda_vcxio,
- .vdac = &omap4_panda_vdac,
- .vusb = &omap4_panda_vusb,
- .vaux2 = &omap4_panda_vaux2,
- .vaux3 = &omap4_panda_vaux3,
- .clk32kg = &omap4_panda_clk32kg,
- .usb = &omap4_usbphy_data,
-
- /* children */
- .codec = &twl6040_codec,
-};
-
-/*
- * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
- * is connected as I2C slave device, and can be accessed at address 0x50
- */
-static struct i2c_board_info __initdata panda_i2c_eeprom[] = {
- {
- I2C_BOARD_INFO("eeprom", 0x50),
- },
-};
-
-static int __init omap4_panda_i2c_init(void)
-{
- omap4_pmic_init("twl6030", &omap4_panda_twldata);
- omap_register_i2c_bus(2, 400, NULL, 0);
- /*
- * Bus 3 is attached to the DVI port where devices like the pico DLP
- * projector don't work reliably with 400kHz
- */
- omap_register_i2c_bus(3, 100, panda_i2c_eeprom,
- ARRAY_SIZE(panda_i2c_eeprom));
- if(ARRAY_SIZE(bus4_i2c_devices))
- omap_register_i2c_bus(4, 400, bus4_i2c_devices, ARRAY_SIZE(bus4_i2c_devices));
- else
- omap_register_i2c_bus(4, 400, NULL, 0);
- return 0;
-}
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
- /* WLAN IRQ - GPIO 53 */
- OMAP4_MUX(GPMC_NCS3, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
- /* WLAN POWER ENABLE - GPIO 43 */
- OMAP4_MUX(GPMC_A19, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT),
- /* WLAN SDIO: MMC5 CMD */
- OMAP4_MUX(SDMMC5_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
- /* WLAN SDIO: MMC5 CLK */
- OMAP4_MUX(SDMMC5_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
- /* WLAN SDIO: MMC5 DAT[0-3] */
- OMAP4_MUX(SDMMC5_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
- OMAP4_MUX(SDMMC5_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
- OMAP4_MUX(SDMMC5_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
- OMAP4_MUX(SDMMC5_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
- /* gpio 0 - TFP410 PD */
- OMAP4_MUX(KPD_COL1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE3),
- /* dispc2_data23 */
- OMAP4_MUX(USBB2_ULPITLL_STP, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data22 */
- OMAP4_MUX(USBB2_ULPITLL_DIR, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data21 */
- OMAP4_MUX(USBB2_ULPITLL_NXT, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data20 */
- OMAP4_MUX(USBB2_ULPITLL_DAT0, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data19 */
- OMAP4_MUX(USBB2_ULPITLL_DAT1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data18 */
- OMAP4_MUX(USBB2_ULPITLL_DAT2, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data15 */
- OMAP4_MUX(USBB2_ULPITLL_DAT3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data14 */
- OMAP4_MUX(USBB2_ULPITLL_DAT4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data13 */
- OMAP4_MUX(USBB2_ULPITLL_DAT5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data12 */
- OMAP4_MUX(USBB2_ULPITLL_DAT6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data11 */
- OMAP4_MUX(USBB2_ULPITLL_DAT7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data10 */
- OMAP4_MUX(DPM_EMU3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data9 */
- OMAP4_MUX(DPM_EMU4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data16 */
- OMAP4_MUX(DPM_EMU5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data17 */
- OMAP4_MUX(DPM_EMU6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_hsync */
- OMAP4_MUX(DPM_EMU7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_pclk */
- OMAP4_MUX(DPM_EMU8, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_vsync */
- OMAP4_MUX(DPM_EMU9, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_de */
- OMAP4_MUX(DPM_EMU10, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data8 */
- OMAP4_MUX(DPM_EMU11, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data7 */
- OMAP4_MUX(DPM_EMU12, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data6 */
- OMAP4_MUX(DPM_EMU13, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data5 */
- OMAP4_MUX(DPM_EMU14, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data4 */
- OMAP4_MUX(DPM_EMU15, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data3 */
- OMAP4_MUX(DPM_EMU16, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data2 */
- OMAP4_MUX(DPM_EMU17, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data1 */
- OMAP4_MUX(DPM_EMU18, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- /* dispc2_data0 */
- OMAP4_MUX(DPM_EMU19, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-
-static inline void __init board_serial_init(void)
-{
- omap_serial_init();
-}
-#else
-#define board_mux NULL
-
-static inline void __init board_serial_init(void)
-{
- omap_serial_init();
-}
-#endif
-
-/* Display DVI */
-#define PANDA_DVI_TFP410_POWER_DOWN_GPIO 0
-
-static int omap4_panda_enable_dvi(struct omap_dss_device *dssdev)
-{
- gpio_set_value(dssdev->reset_gpio, 1);
- return 0;
-}
-
-static void omap4_panda_disable_dvi(struct omap_dss_device *dssdev)
-{
- gpio_set_value(dssdev->reset_gpio, 0);
-}
-
-/* Using generic display panel */
-static struct panel_generic_dpi_data omap4_dvi_panel = {
- .name = "generic_720p",
- .platform_enable = omap4_panda_enable_dvi,
- .platform_disable = omap4_panda_disable_dvi,
-};
-
-struct omap_dss_device omap4_panda_dvi_device = {
- .type = OMAP_DISPLAY_TYPE_DPI,
- .name = "dvi",
- .driver_name = "generic_dpi_panel",
- .data = &omap4_dvi_panel,
- .phy.dpi.data_lines = 24,
- .reset_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO,
- .channel = OMAP_DSS_CHANNEL_LCD2,
-};
-
-int __init omap4_panda_dvi_init(void)
-{
- int r;
-
- /* Requesting TFP410 DVI GPIO and disabling it, at bootup */
- r = gpio_request_one(omap4_panda_dvi_device.reset_gpio,
- GPIOF_OUT_INIT_LOW, "DVI PD");
- if (r)
- pr_err("Failed to get DVI powerdown GPIO\n");
-
- return r;
-}
-
-static struct gpio panda_hdmi_gpios[] = {
- { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" },
- { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
-};
-
-static void omap4_panda_hdmi_mux_init(void)
-{
- u32 r;
- int status;
- /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
- omap_mux_init_signal("hdmi_hpd.hdmi_hpd",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("gpmc_wait2.gpio_100",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hdmi_cec.hdmi_cec",
- OMAP_PIN_INPUT_PULLUP);
- /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
- omap_mux_init_signal("hdmi_ddc_scl.hdmi_ddc_scl",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("hdmi_ddc_sda.hdmi_ddc_sda",
- OMAP_PIN_INPUT_PULLUP);
-
- /* strong pullup on DDC lines using unpublished register */
- r = ((1 << 24) | (1 << 28)) ;
- omap4_ctrl_pad_writel(r, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_1);
-
- gpio_request(HDMI_GPIO_HPD, NULL);
- omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT | OMAP_PULL_ENA);
- gpio_direction_input(HDMI_GPIO_HPD);
-
- status = gpio_request_array(panda_hdmi_gpios,
- ARRAY_SIZE(panda_hdmi_gpios));
- if (status)
- pr_err("%s: Cannot request HDMI GPIOs %x \n", __func__, status);
-}
-
-static struct omap_dss_device omap4_panda_hdmi_device = {
- .name = "hdmi",
- .driver_name = "hdmi_panel",
- .type = OMAP_DISPLAY_TYPE_HDMI,
- .clocks = {
- .dispc = {
- .dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
- },
- .hdmi = {
- .regn = 15,
- .regm2 = 1,
- },
- },
- .hpd_gpio = HDMI_GPIO_HPD,
- .channel = OMAP_DSS_CHANNEL_DIGIT,
-};
-
-static struct omap_dss_device *omap4_panda_dss_devices[] = {
- &omap4_panda_dvi_device,
- &omap4_panda_hdmi_device,
-};
-
-static struct omap_dss_board_info omap4_panda_dss_data = {
- .num_devices = ARRAY_SIZE(omap4_panda_dss_devices),
- .devices = omap4_panda_dss_devices,
- .default_device = &omap4_panda_dvi_device,
-};
-
-/*
- * LPDDR2 Configeration Data:
- * The memory organisation is as below :
- * EMIF1 - CS0 - 2 Gb
- * CS1 - 2 Gb
- * EMIF2 - CS0 - 2 Gb
- * CS1 - 2 Gb
- * --------------------
- * TOTAL - 8 Gb
- *
- * Same devices installed on EMIF1 and EMIF2
- */
-static __initdata struct emif_device_details emif_devices = {
- .cs0_device = &lpddr2_elpida_2G_S4_dev,
- .cs1_device = &lpddr2_elpida_2G_S4_dev
-};
-
-void omap4_panda_display_init(void)
-{
- int r;
-
- r = omap4_panda_dvi_init();
- if (r)
- pr_err("error initializing panda DVI\n");
-
- omap4_panda_hdmi_mux_init();
- omap_display_init(&omap4_panda_dss_data);
-}
-
-static int panda_notifier_call(struct notifier_block *this,
- unsigned long code, void *cmd)
-{
- void __iomem *sar_base;
- u32 v = OMAP4430_RST_GLOBAL_COLD_SW_MASK;
-
- sar_base = omap4_get_sar_ram_base();
-
- if (!sar_base)
- return notifier_from_errno(-ENOMEM);
-
- if ((code == SYS_RESTART) && (cmd != NULL)) {
- /* cmd != null; case: warm boot */
- if (!strcmp(cmd, "bootloader")) {
- /* Save reboot mode in scratch memory */
- strcpy(sar_base + 0xA0C, cmd);
- v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
- } else if (!strcmp(cmd, "recovery")) {
- /* Save reboot mode in scratch memory */
- strcpy(sar_base + 0xA0C, cmd);
- v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
- } else {
- v |= OMAP4430_RST_GLOBAL_COLD_SW_MASK;
- }
- }
-
- omap4_prm_write_inst_reg(0xfff, OMAP4430_PRM_DEVICE_INST,
- OMAP4_RM_RSTST);
- omap4_prm_write_inst_reg(v, OMAP4430_PRM_DEVICE_INST, OMAP4_RM_RSTCTRL);
- v = omap4_prm_read_inst_reg(WKUP_MOD, OMAP4_RM_RSTCTRL);
-
- return NOTIFY_DONE;
-}
-
-static struct notifier_block panda_reboot_notifier = {
- .notifier_call = panda_notifier_call,
-};
-
-#define PANDA_FB_RAM_SIZE SZ_16M /* 1920?1080*4 * 2 */
-static struct omapfb_platform_data panda_fb_pdata = {
- .mem_desc = {
- .region_cnt = 1,
- .region = {
- [0] = {
- .size = PANDA_FB_RAM_SIZE,
- },
- },
- },
-};
-
-static struct resource ramconsole_resources[] = {
- {
- .flags = IORESOURCE_MEM,
- .start = PANDA_RAMCONSOLE_START,
- .end = PANDA_RAMCONSOLE_START + PANDA_RAMCONSOLE_SIZE - 1,
- },
-};
-
-static struct ram_console_platform_data ramconsole_pdata;
-
-static struct platform_device ramconsole_device = {
- .name = "ram_console",
- .id = -1,
- .num_resources = ARRAY_SIZE(ramconsole_resources),
- .resource = ramconsole_resources,
- .dev = {
- .platform_data = &ramconsole_pdata,
- },
-};
-
-extern void __init omap4_panda_android_init(void);
-
-static void __init omap4_panda_init(void)
-{
- int package = OMAP_PACKAGE_CBS;
- int status;
-
- omap_emif_setup_device_details(&emif_devices, &emif_devices);
-
- if (omap_rev() == OMAP4430_REV_ES1_0)
- package = OMAP_PACKAGE_CBL;
- omap4_mux_init(board_mux, NULL, package);
-
- if (wl12xx_set_platform_data(&omap_panda_wlan_data))
- pr_err("error setting wl12xx data\n");
-
- register_reboot_notifier(&panda_reboot_notifier);
- ramconsole_pdata.bootinfo = omap4_get_resetreason();
- platform_device_register(&ramconsole_device);
- omap4_panda_i2c_init();
- omap4_audio_conf();
-
- if (cpu_is_omap4430())
- panda_gpio_keys_buttons[0].gpio = 121;
-
- platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
- platform_device_register(&omap_vwlan_device);
- board_serial_init();
- omap4_twl6030_hsmmc_init(mmc);
- omap4_ehci_init();
- usb_musb_init(&musb_board_data);
-
- omap_dmm_init();
- omap_vram_set_sdram_vram(PANDA_FB_RAM_SIZE, 0);
- omapfb_set_platform_data(&panda_fb_pdata);
- omap4_panda_display_init();
-
- if (cpu_is_omap446x()) {
- /* Vsel0 = gpio, vsel1 = gnd */
- status = omap_tps6236x_board_setup(true, TPS62361_GPIO, -1,
- OMAP_PIN_OFF_OUTPUT_HIGH, -1);
- if (status)
- pr_err("TPS62361 initialization failed: %d\n", status);
- }
- omap_enable_smartreflex_on_init();
-}
-
-static void __init omap4_panda_map_io(void)
-{
- omap2_set_globals_443x();
- omap44xx_map_common_io();
-}
-
-static void __init omap4_panda_reserve(void)
-{
- /* do the static reservations first */
- memblock_remove(PANDA_RAMCONSOLE_START, PANDA_RAMCONSOLE_SIZE);
- memblock_remove(PHYS_ADDR_SMC_MEM, PHYS_ADDR_SMC_SIZE);
- memblock_remove(PHYS_ADDR_DUCATI_MEM, PHYS_ADDR_DUCATI_SIZE);
- /* ipu needs to recognize secure input buffer area as well */
- omap_ipu_set_static_mempool(PHYS_ADDR_DUCATI_MEM, PHYS_ADDR_DUCATI_SIZE +
- OMAP_ION_HEAP_SECURE_INPUT_SIZE);
-
- omap_reserve();
-}
-
-MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
- /* Maintainer: David Anders - Texas Instruments Inc */
- .boot_params = 0x80000100,
- .reserve = omap4_panda_reserve,
- .map_io = omap4_panda_map_io,
- .init_early = omap4_panda_init_early,
- .init_irq = gic_init_irq,
- .init_machine = omap4_panda_init,
- .timer = &omap_timer,
-MACHINE_END
diff --git a/kernel/drivers/input/touchscreen/Kconfig b/kernel/drivers/input/touchscreen/Kconfig
deleted file mode 100644
index 18655c0b3997..000000000000
--- a/kernel/drivers/input/touchscreen/Kconfig
+++ /dev/null
@@ -1,721 +0,0 @@
-#
-# Touchscreen driver configuration
-#
-menuconfig INPUT_TOUCHSCREEN
- bool "Touchscreens"
- help
- Say Y here, and a list of supported touchscreens will be displayed.
- This option doesn't affect the kernel.
-
- If unsure, say Y.
-
-if INPUT_TOUCHSCREEN
-
-config TOUCHSCREEN_88PM860X
- tristate "Marvell 88PM860x touchscreen"
- depends on MFD_88PM860X
- help
- Say Y here if you have a 88PM860x PMIC and want to enable
- support for the built-in touchscreen.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called 88pm860x-ts.
-
-config TOUCHSCREEN_ADS7846
- tristate "ADS7846/TSC2046/AD7873 and AD(S)7843 based touchscreens"
- depends on SPI_MASTER
- depends on HWMON = n || HWMON
- help
- Say Y here if you have a touchscreen interface using the
- ADS7846/TSC2046/AD7873 or ADS7843/AD7843 controller,
- and your board-specific setup code includes that in its
- table of SPI devices.
-
- If HWMON is selected, and the driver is told the reference voltage
- on your board, you will also get hwmon interfaces for the voltage
- (and on ads7846/tsc2046/ad7873, temperature) sensors of this chip.
-
- If unsure, say N (but it's safe to say "Y").
-
- To compile this driver as a module, choose M here: the
- module will be called ads7846.
-
-config TOUCHSCREEN_AD7877
- tristate "AD7877 based touchscreens"
- depends on SPI_MASTER
- help
- Say Y here if you have a touchscreen interface using the
- AD7877 controller, and your board-specific initialization
- code includes that in its table of SPI devices.
-
- If unsure, say N (but it's safe to say "Y").
-
- To compile this driver as a module, choose M here: the
- module will be called ad7877.
-
-config TOUCHSCREEN_AD7879
- tristate "Analog Devices AD7879-1/AD7889-1 touchscreen interface"
- help
- Say Y here if you want to support a touchscreen interface using
- the AD7879-1/AD7889-1 controller.
-
- You should select a bus connection too.
-
- To compile this driver as a module, choose M here: the
- module will be called ad7879.
-
-config TOUCHSCREEN_AD7879_I2C
- tristate "support I2C bus connection"
- depends on TOUCHSCREEN_AD7879 && I2C
- help
- Say Y here if you have AD7879-1/AD7889-1 hooked to an I2C bus.
-
- To compile this driver as a module, choose M here: the
- module will be called ad7879-i2c.
-
-config TOUCHSCREEN_AD7879_SPI
- tristate "support SPI bus connection"
- depends on TOUCHSCREEN_AD7879 && SPI_MASTER
- help
- Say Y here if you have AD7879-1/AD7889-1 hooked to a SPI bus.
-
- If unsure, say N (but it's safe to say "Y").
-
- To compile this driver as a module, choose M here: the
- module will be called ad7879-spi.
-
-config TOUCHSCREEN_BITSY
- tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
- depends on SA1100_BITSY
- select SERIO
- help
- Say Y here if you have the h3600 (Bitsy) touchscreen.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called h3600_ts_input.
-
-config TOUCHSCREEN_BU21013
- tristate "BU21013 based touch panel controllers"
- depends on I2C
- help
- Say Y here if you have a bu21013 touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called bu21013_ts.
-
-config TOUCHSCREEN_CY8CTMG110
- tristate "cy8ctmg110 touchscreen"
- depends on I2C
- depends on GPIOLIB
-
- help
- Say Y here if you have a cy8ctmg110 capacitive touchscreen on
- an AAVA device.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called cy8ctmg110_ts.
-
-config TOUCHSCREEN_DA9034
- tristate "Touchscreen support for Dialog Semiconductor DA9034"
- depends on PMIC_DA903X
- default y
- help
- Say Y here to enable the support for the touchscreen found
- on Dialog Semiconductor DA9034 PMIC.
-
-config TOUCHSCREEN_DYNAPRO
- tristate "Dynapro serial touchscreen"
- select SERIO
- help
- Say Y here if you have a Dynapro serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called dynapro.
-
-config TOUCHSCREEN_HAMPSHIRE
- tristate "Hampshire serial touchscreen"
- select SERIO
- help
- Say Y here if you have a Hampshire serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called hampshire.
-
-config TOUCHSCREEN_EETI
- tristate "EETI touchscreen panel support"
- depends on I2C
- help
- Say Y here to enable support for I2C connected EETI touch panels.
-
- To compile this driver as a module, choose M here: the
- module will be called eeti_ts.
-
-config TOUCHSCREEN_FUJITSU
- tristate "Fujitsu serial touchscreen"
- select SERIO
- help
- Say Y here if you have the Fujitsu touchscreen (such as one
- installed in Lifebook P series laptop) connected to your
- system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called fujitsu-ts.
-
-config TOUCHSCREEN_S3C2410
- tristate "Samsung S3C2410/generic touchscreen input driver"
- depends on ARCH_S3C2410 || SAMSUNG_DEV_TS
- select S3C_ADC
- help
- Say Y here if you have the s3c2410 touchscreen.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called s3c2410_ts.
-
-config TOUCHSCREEN_GUNZE
- tristate "Gunze AHL-51S touchscreen"
- select SERIO
- help
- Say Y here if you have the Gunze AHL-51 touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called gunze.
-
-config TOUCHSCREEN_ELO
- tristate "Elo serial touchscreens"
- select SERIO
- help
- Say Y here if you have an Elo serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called elo.
-
-config TOUCHSCREEN_WACOM_W8001
- tristate "Wacom W8001 penabled serial touchscreen"
- select SERIO
- help
- Say Y here if you have an Wacom W8001 penabled serial touchscreen
- connected to your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called wacom_w8001.
-
-config TOUCHSCREEN_LPC32XX
- tristate "LPC32XX touchscreen controller"
- depends on ARCH_LPC32XX
- help
- Say Y here if you have a LPC32XX device and want
- to support the built-in touchscreen.
-
- To compile this driver as a module, choose M here: the
- module will be called lpc32xx_ts.
-
-config TOUCHSCREEN_MCS5000
- tristate "MELFAS MCS-5000 touchscreen"
- depends on I2C
- help
- Say Y here if you have the MELFAS MCS-5000 touchscreen controller
- chip in your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called mcs5000_ts.
-
-config TOUCHSCREEN_MTOUCH
- tristate "MicroTouch serial touchscreens"
- select SERIO
- help
- Say Y here if you have a MicroTouch (3M) serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called mtouch.
-
-config TOUCHSCREEN_INEXIO
- tristate "iNexio serial touchscreens"
- select SERIO
- help
- Say Y here if you have an iNexio serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called inexio.
-
-config TOUCHSCREEN_INTEL_MID
- tristate "Intel MID platform resistive touchscreen"
- depends on INTEL_SCU_IPC
- help
- Say Y here if you have a Intel MID based touchscreen in
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called intel_mid_touch.
-
-config TOUCHSCREEN_MK712
- tristate "ICS MicroClock MK712 touchscreen"
- help
- Say Y here if you have the ICS MicroClock MK712 touchscreen
- controller chip in your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called mk712.
-
-config TOUCHSCREEN_HP600
- tristate "HP Jornada 6xx touchscreen"
- depends on SH_HP6XX && SH_ADC
- help
- Say Y here if you have a HP Jornada 620/660/680/690 and want to
- support the built-in touchscreen.
-
- To compile this driver as a module, choose M here: the
- module will be called hp680_ts_input.
-
-config TOUCHSCREEN_HP7XX
- tristate "HP Jornada 7xx touchscreen"
- depends on SA1100_JORNADA720_SSP
- help
- Say Y here if you have a HP Jornada 710/720/728 and want
- to support the built-in touchscreen.
-
- To compile this driver as a module, choose M here: the
- module will be called jornada720_ts.
-
-config TOUCHSCREEN_HTCPEN
- tristate "HTC Shift X9500 touchscreen"
- depends on ISA
- help
- Say Y here if you have an HTC Shift UMPC also known as HTC X9500
- Clio / Shangrila and want to support the built-in touchscreen.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called htcpen.
-
-config TOUCHSCREEN_PENMOUNT
- tristate "Penmount serial touchscreen"
- select SERIO
- help
- Say Y here if you have a Penmount serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called penmount.
-
-config TOUCHSCREEN_QT602240
- tristate "QT602240 I2C Touchscreen"
- depends on I2C
- help
- Say Y here if you have the AT42QT602240/ATMXT224 I2C touchscreen
- connected to your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called qt602240_ts.
-
-config TOUCHSCREEN_MIGOR
- tristate "Renesas MIGO-R touchscreen"
- depends on SH_MIGOR && I2C
- help
- Say Y here to enable MIGO-R touchscreen support.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called migor_ts.
-
-config TOUCHSCREEN_TNETV107X
- tristate "TI TNETV107X touchscreen support"
- depends on ARCH_DAVINCI_TNETV107X
- help
- Say Y here if you want to use the TNETV107X touchscreen.
-
- To compile this driver as a module, choose M here: the
- module will be called tnetv107x-ts.
-
-config TOUCHSCREEN_SYNAPTICS_I2C_RMI4
- tristate "Synaptics DSX I2C touchscreen"
- depends on I2C
- help
- Say Y here if you have a Synaptics DSX I2C touchscreen
- connected to your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called synaptics_i2c_rmi4.
-
-config TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV
- tristate "Synaptics I2C touchscreen rmi device"
- depends on TOUCHSCREEN_SYNAPTICS_I2C_RMI4
- help
- This enables support for character device channel for Synaptics RMI
- touchscreens.
-
-config TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE
- tristate "Synaptics I2C touchscreen firmware update"
- depends on TOUCHSCREEN_SYNAPTICS_I2C_RMI4
- help
- This enables support for firmware update for Synaptics RMI
- touchscreens.
-
-config TOUCHSCREEN_TOUCHRIGHT
- tristate "Touchright serial touchscreen"
- select SERIO
- help
- Say Y here if you have a Touchright serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called touchright.
-
-config TOUCHSCREEN_TOUCHWIN
- tristate "Touchwin serial touchscreen"
- select SERIO
- help
- Say Y here if you have a Touchwin serial touchscreen connected to
- your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called touchwin.
-
-config TOUCHSCREEN_ATMEL_TSADCC
- tristate "Atmel Touchscreen Interface"
- depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
- help
- Say Y here if you have a 4-wire touchscreen connected to the
- ADC Controller on your Atmel SoC (such as the AT91SAM9RL).
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called atmel_tsadcc.
-
-config TOUCHSCREEN_UCB1400
- tristate "Philips UCB1400 touchscreen"
- depends on AC97_BUS
- depends on UCB1400_CORE
- help
- This enables support for the Philips UCB1400 touchscreen interface.
- The UCB1400 is an AC97 audio codec. The touchscreen interface
- will be initialized only after the ALSA subsystem has been
- brought up and the UCB1400 detected. You therefore have to
- configure ALSA support as well (either built-in or modular,
- independently of whether this driver is itself built-in or
- modular) for this driver to work.
-
- To compile this driver as a module, choose M here: the
- module will be called ucb1400_ts.
-
-config TOUCHSCREEN_WM97XX
- tristate "Support for WM97xx AC97 touchscreen controllers"
- depends on AC97_BUS
- help
- Say Y here if you have a Wolfson Microelectronics WM97xx
- touchscreen connected to your system. Note that this option
- only enables core driver, you will also need to select
- support for appropriate chip below.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called wm97xx-ts.
-
-config TOUCHSCREEN_WM9705
- bool "WM9705 Touchscreen interface support"
- depends on TOUCHSCREEN_WM97XX
- default y
- help
- Say Y here to enable support for the Wolfson Microelectronics
- WM9705 touchscreen controller.
-
-config TOUCHSCREEN_WM9712
- bool "WM9712 Touchscreen interface support"
- depends on TOUCHSCREEN_WM97XX
- default y
- help
- Say Y here to enable support for the Wolfson Microelectronics
- WM9712 touchscreen controller.
-
-config TOUCHSCREEN_WM9713
- bool "WM9713 Touchscreen interface support"
- depends on TOUCHSCREEN_WM97XX
- default y
- help
- Say Y here to enable support for the Wolfson Microelectronics
- WM9713 touchscreen controller.
-
-config TOUCHSCREEN_WM97XX_ATMEL
- tristate "WM97xx Atmel accelerated touch"
- depends on TOUCHSCREEN_WM97XX && (AVR32 || ARCH_AT91)
- help
- Say Y here for support for streaming mode with WM97xx touchscreens
- on Atmel AT91 or AVR32 systems with an AC97C module.
-
- Be aware that this will use channel B in the controller for
- streaming data, this must not conflict with other AC97C drivers.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the module will
- be called atmel-wm97xx.
-
-config TOUCHSCREEN_WM97XX_MAINSTONE
- tristate "WM97xx Mainstone/Palm accelerated touch"
- depends on TOUCHSCREEN_WM97XX && ARCH_PXA
- help
- Say Y here for support for streaming mode with WM97xx touchscreens
- on Mainstone, Palm Tungsten T5, TX and LifeDrive systems.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called mainstone-wm97xx.
-
-config TOUCHSCREEN_WM97XX_ZYLONITE
- tristate "Zylonite accelerated touch"
- depends on TOUCHSCREEN_WM97XX && MACH_ZYLONITE
- select TOUCHSCREEN_WM9713
- help
- Say Y here for support for streaming mode with the touchscreen
- on Zylonite systems.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called zylonite-wm97xx.
-
-config TOUCHSCREEN_USB_COMPOSITE
- tristate "USB Touchscreen Driver"
- depends on USB_ARCH_HAS_HCD
- select USB
- help
- USB Touchscreen driver for:
- - eGalax Touchkit USB (also includes eTurboTouch CT-410/510/700)
- - PanJit TouchSet USB
- - 3M MicroTouch USB (EX II series)
- - ITM
- - some other eTurboTouch
- - Gunze AHL61
- - DMC TSC-10/25
- - IRTOUCHSYSTEMS/UNITOP
- - IdealTEK URTC1000
- - GoTop Super_Q2/GogoPen/PenPower tablets
- - JASTEC USB Touch Controller/DigiTech DTR-02U
- - Zytronic controllers
-
- Have a look at <http://linux.chapter7.ch/touchkit/> for
- a usage description and the required user-space stuff.
-
- To compile this driver as a module, choose M here: the
- module will be called usbtouchscreen.
-
-config TOUCHSCREEN_MC13783
- tristate "Freescale MC13783 touchscreen input driver"
- depends on MFD_MC13783
- help
- Say Y here if you have an Freescale MC13783 PMIC on your
- board and want to use its touchscreen
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called mc13783_ts.
-
-config TOUCHSCREEN_USB_EGALAX
- default y
- bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_PANJIT
- default y
- bool "PanJit device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_3M
- default y
- bool "3M/Microtouch EX II series device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_ITM
- default y
- bool "ITM device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_ETURBO
- default y
- bool "eTurboTouch (non-eGalax compatible) device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_GUNZE
- default y
- bool "Gunze AHL61 device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_DMC_TSC10
- default y
- bool "DMC TSC-10/25 device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_IRTOUCH
- default y
- bool "IRTOUCHSYSTEMS/UNITOP device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_IDEALTEK
- default y
- bool "IdealTEK URTC1000 device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_GENERAL_TOUCH
- default y
- bool "GeneralTouch Touchscreen device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_GOTOP
- default y
- bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_JASTEC
- default y
- bool "JASTEC/DigiTech DTR-02U USB touch controller device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_E2I
- default y
- bool "e2i Touchscreen controller (e.g. from Mimo 740)"
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_ZYTRONIC
- default y
- bool "Zytronic controller" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_ETT_TC45USB
- default y
- bool "ET&T USB series TC4UM/TC5UH touchscreen controler support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_USB_NEXIO
- default y
- bool "NEXIO/iNexio device support" if EMBEDDED
- depends on TOUCHSCREEN_USB_COMPOSITE
-
-config TOUCHSCREEN_TOUCHIT213
- tristate "Sahara TouchIT-213 touchscreen"
- select SERIO
- help
- Say Y here if you have a Sahara TouchIT-213 Tablet PC.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called touchit213.
-
-config TOUCHSCREEN_TSC2007
- tristate "TSC2007 based touchscreens"
- depends on I2C
- help
- Say Y here if you have a TSC2007 based touchscreen.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called tsc2007.
-
-config TOUCHSCREEN_TSC2004
- tristate "TSC2004 based touchscreens"
- depends on I2C
- help
- Say Y here if you have a TSC2004 based touchscreen.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called tsc2004.
-
-config TOUCHSCREEN_W90X900
- tristate "W90P910 touchscreen driver"
- depends on HAVE_CLK
- help
- Say Y here if you have a W90P910 based touchscreen.
-
- To compile this driver as a module, choose M here: the
- module will be called w90p910_ts.
-
-config TOUCHSCREEN_PCAP
- tristate "Motorola PCAP touchscreen"
- depends on EZX_PCAP
- help
- Say Y here if you have a Motorola EZX telephone and
- want to enable support for the built-in touchscreen.
-
- To compile this driver as a module, choose M here: the
- module will be called pcap_ts.
-
-config TOUCHSCREEN_TPS6507X
- tristate "TPS6507x based touchscreens"
- depends on I2C
- help
- Say Y here if you have a TPS6507x based touchscreen
- controller.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called tps6507x_ts.
-
-config TOUCHSCREEN_STMPE
- tristate "STMicroelectronics STMPE touchscreens"
- depends on MFD_STMPE
- help
- Say Y here if you want support for STMicroelectronics
- STMPE touchscreen controllers.
-
- To compile this driver as a module, choose M here: the
- module will be called stmpe-ts.
-
-endif
diff --git a/kernel/drivers/input/touchscreen/Makefile b/kernel/drivers/input/touchscreen/Makefile
deleted file mode 100644
index a6c7d9f388a6..000000000000
--- a/kernel/drivers/input/touchscreen/Makefile
+++ /dev/null
@@ -1,68 +0,0 @@
-#
-# Makefile for the touchscreen drivers.
-#
-
-# Each configuration option enables a list of files.
-
-wm97xx-ts-y := wm97xx-core.o
-
-obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o
-obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o
-obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o
-obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o
-obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o
-obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
-obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o
-obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
-obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o
-obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o
-obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o
-obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o
-obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o
-obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
-obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o
-obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
-obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
-obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
-obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o
-obj-$(CONFIG_TOUCHSCREEN_LPC32XX) += lpc32xx_ts.o
-obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o
-obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o
-obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o
-obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
-obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
-obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
-obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o
-obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o
-obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o
-obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o
-obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
-obj-$(CONFIG_TOUCHSCREEN_QT602240) += qt602240_ts.o
-obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o
-obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o
-obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o
-obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += synaptics_i2c_rmi4.o
-obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV) += synaptics_rmi_dev.o
-obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE) += synaptics_fw_update.o
-obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o
-obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
-obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
-obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o
-obj-$(CONFIG_TOUCHSCREEN_TSC2004) += tsc2004.o
-obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
-obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o
-obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o
-wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o
-wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o
-wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o
-obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o
-obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o
-obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o
-obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o
-obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o
-
-all:
-make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
-
-clean:
-make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
diff --git a/kernel/drivers/input/touchscreen/synaptics_fw_update.c b/kernel/drivers/input/touchscreen/synaptics_fw_update.c
deleted file mode 100644
index 8b6d7c7e368d..000000000000
--- a/kernel/drivers/input/touchscreen/synaptics_fw_update.c
+++ /dev/null
@@ -1,1698 +0,0 @@
-/*
- * Synaptics RMI4 touchscreen driver
- *
- * Copyright (C) 2012 Synaptics Incorporated
- *
- * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
- * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/input.h>
-#include <linux/firmware.h>
-#include <linux/input/synaptics_dsx.h>
-#include "synaptics_i2c_rmi4.h"
-
-#define DEBUG_FW_UPDATE
-#define SHOW_PROGRESS
-#define FW_IMAGE_NAME "PR1063486-s7301_00000000.img"
-#define MAX_FIRMWARE_ID_LEN 10
-#define FORCE_UPDATE false
-#define INSIDE_FIRMWARE_UPDATE
-
-#define CHECKSUM_OFFSET 0x00
-#define BOOTLOADER_VERSION_OFFSET 0x07
-#define IMAGE_SIZE_OFFSET 0x08
-#define CONFIG_SIZE_OFFSET 0x0C
-#define PRODUCT_ID_OFFSET 0x10
-#define PRODUCT_INFO_OFFSET 0x1E
-#define FW_IMAGE_OFFSET 0x100
-#define PRODUCT_ID_SIZE 10
-
-#define BOOTLOADER_ID_OFFSET 0
-#define FLASH_PROPERTIES_OFFSET 2
-#define BLOCK_SIZE_OFFSET 3
-#define FW_BLOCK_COUNT_OFFSET 5
-
-#define REG_MAP (1 << 0)
-#define UNLOCKED (1 << 1)
-#define HAS_CONFIG_ID (1 << 2)
-#define HAS_PERM_CONFIG (1 << 3)
-#define HAS_BL_CONFIG (1 << 4)
-#define HAS_DISP_CONFIG (1 << 5)
-#define HAS_CTRL1 (1 << 6)
-
-#define BLOCK_NUMBER_OFFSET 0
-#define BLOCK_DATA_OFFSET 2
-
-#define UI_CONFIG_AREA 0x00
-#define PERM_CONFIG_AREA 0x01
-#define BL_CONFIG_AREA 0x02
-#define DISP_CONFIG_AREA 0x03
-
-enum flash_command {
- CMD_WRITE_FW_BLOCK = 0x2,
- CMD_ERASE_ALL = 0x3,
- CMD_READ_CONFIG_BLOCK = 0x5,
- CMD_WRITE_CONFIG_BLOCK = 0x6,
- CMD_ERASE_CONFIG = 0x7,
- CMD_ERASE_BL_CONFIG = 0x9,
- CMD_ERASE_DISP_CONFIG = 0xA,
- CMD_ENABLE_FLASH_PROG = 0xF,
-};
-
-enum flash_area {
- NONE,
- UI_FIRMWARE,
- CONFIG_AREA
-};
-
-#define SLEEP_MODE_NORMAL (0x00)
-#define SLEEP_MODE_SENSOR_SLEEP (0x01)
-#define SLEEP_MODE_RESERVED0 (0x02)
-#define SLEEP_MODE_RESERVED1 (0x03)
-
-#define ENABLE_WAIT_MS (1 * 1000)
-#define WRITE_WAIT_MS (3 * 1000)
-#define ERASE_WAIT_MS (5 * 1000)
-#define RESET_WAIT_MS (500)
-
-#define SLEEP_TIME_US 50
-
-static ssize_t fwu_sysfs_show_image(struct file *data_file,
- struct kobject *kobj, struct bin_attribute *attributes,
- char *buf, loff_t pos, size_t count);
-
-static ssize_t fwu_sysfs_store_image(struct file *data_file,
- struct kobject *kobj, struct bin_attribute *attributes,
- char *buf, loff_t pos, size_t count);
-
-static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t fwu_sysfs_write_config_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t fwu_sysfs_read_config_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t fwu_sysfs_config_area_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t fwu_sysfs_image_size_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t fwu_sysfs_block_size_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static int fwu_wait_for_idle(int timeout_ms);
-
-struct image_header {
- unsigned int checksum;
- unsigned int image_size;
- unsigned int config_size;
- unsigned char options;
- unsigned char bootloader_version;
- unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
- unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE];
-};
-
-struct pdt_properties {
- union {
- struct {
- unsigned char reserved_1:6;
- unsigned char has_bsr:1;
- unsigned char reserved_2:1;
- } __packed;
- unsigned char data[1];
- };
-};
-
-struct f01_device_status {
- union {
- struct {
- unsigned char status_code:4;
- unsigned char reserved:2;
- unsigned char flash_prog:1;
- unsigned char unconfigured:1;
- } __packed;
- unsigned char data[1];
- };
-};
-
-struct f01_device_control {
- union {
- struct {
- unsigned char sleep_mode:2;
- unsigned char nosleep:1;
- unsigned char reserved:2;
- unsigned char charger_connected:1;
- unsigned char report_rate:1;
- unsigned char configured:1;
- } __packed;
- unsigned char data[1];
- };
-};
-
-struct f34_flash_control {
- union {
- struct {
- unsigned char command:4;
- unsigned char status:3;
- unsigned char program_enabled:1;
- } __packed;
- unsigned char data[1];
- };
-};
-
-struct f34_flash_properties {
- union {
- struct {
- unsigned char regmap:1;
- unsigned char unlocked:1;
- unsigned char has_configid:1;
- unsigned char has_perm_config:1;
- unsigned char has_bl_config:1;
- unsigned char has_display_config:1;
- unsigned char has_blob_config:1;
- unsigned char reserved:1;
- } __packed;
- unsigned char data[1];
- };
-};
-
-struct synaptics_rmi4_fwu_handle {
- bool initialized;
- bool force_update;
- char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
- unsigned int image_size;
- unsigned int data_pos;
- unsigned char intr_mask;
- unsigned char bootloader_id[2];
- unsigned char productinfo1;
- unsigned char productinfo2;
- unsigned char *ext_data_source;
- unsigned char *read_config_buf;
- const unsigned char *firmware_data;
- const unsigned char *config_data;
- unsigned short block_size;
- unsigned short fw_block_count;
- unsigned short config_block_count;
- unsigned short perm_config_block_count;
- unsigned short bl_config_block_count;
- unsigned short disp_config_block_count;
- unsigned short config_size;
- unsigned short config_area;
- unsigned short addr_f34_flash_control;
- unsigned short addr_f01_interrupt_register;
- struct synaptics_rmi4_fn_desc f01_fd;
- struct synaptics_rmi4_fn_desc f34_fd;
- struct synaptics_rmi4_exp_fn_ptr *fn_ptr;
- struct synaptics_rmi4_data *rmi4_data;
- struct f34_flash_control flash_control;
- struct f34_flash_properties flash_properties;
- struct workqueue_struct *fwu_workqueue;
- struct delayed_work fwu_work;
-};
-
-static struct bin_attribute dev_attr_data = {
- .attr = {
- .name = "data",
- .mode = (S_IRUGO | S_IWUGO),
- },
- .size = 0,
- .read = fwu_sysfs_show_image,
- .write = fwu_sysfs_store_image,
-};
-
-static struct device_attribute attrs[] = {
- __ATTR(doreflash, S_IWUGO,
- synaptics_rmi4_show_error,
- fwu_sysfs_do_reflash_store),
- __ATTR(writeconfig, S_IWUGO,
- synaptics_rmi4_show_error,
- fwu_sysfs_write_config_store),
- __ATTR(readconfig, S_IWUGO,
- synaptics_rmi4_show_error,
- fwu_sysfs_read_config_store),
- __ATTR(configarea, S_IWUGO,
- synaptics_rmi4_show_error,
- fwu_sysfs_config_area_store),
- __ATTR(imagesize, S_IWUGO,
- synaptics_rmi4_show_error,
- fwu_sysfs_image_size_store),
- __ATTR(blocksize, S_IRUGO,
- fwu_sysfs_block_size_show,
- synaptics_rmi4_store_error),
- __ATTR(fwblockcount, S_IRUGO,
- fwu_sysfs_firmware_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(configblockcount, S_IRUGO,
- fwu_sysfs_configuration_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(permconfigblockcount, S_IRUGO,
- fwu_sysfs_perm_config_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(blconfigblockcount, S_IRUGO,
- fwu_sysfs_bl_config_block_count_show,
- synaptics_rmi4_store_error),
- __ATTR(dispconfigblockcount, S_IRUGO,
- fwu_sysfs_disp_config_block_count_show,
- synaptics_rmi4_store_error),
-};
-
-static struct synaptics_rmi4_fwu_handle *fwu;
-
-static struct completion remove_complete;
-
-static unsigned int extract_uint(const unsigned char *ptr)
-{
- return (unsigned int)ptr[0] +
- (unsigned int)ptr[1] * 0x100 +
- (unsigned int)ptr[2] * 0x10000 +
- (unsigned int)ptr[3] * 0x1000000;
-}
-
-static void parse_header(struct image_header *header,
- const unsigned char *fw_image)
-{
- header->checksum = extract_uint(&fw_image[CHECKSUM_OFFSET]);
- header->bootloader_version = fw_image[BOOTLOADER_VERSION_OFFSET];
- header->image_size = extract_uint(&fw_image[IMAGE_SIZE_OFFSET]);
- header->config_size = extract_uint(&fw_image[CONFIG_SIZE_OFFSET]);
- memcpy(header->product_id, &fw_image[PRODUCT_ID_OFFSET],
- SYNAPTICS_RMI4_PRODUCT_ID_SIZE);
- header->product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE] = 0;
- memcpy(header->product_info, &fw_image[PRODUCT_INFO_OFFSET],
- SYNAPTICS_RMI4_PRODUCT_INFO_SIZE);
-
-#ifdef DEBUG_FW_UPDATE
- dev_info(&fwu->rmi4_data->i2c_client->dev,
- "Firwmare size %d, config size %d\n",
- header->image_size,
- header->config_size);
-#endif
- return;
-}
-
-static int fwu_read_f01_device_status(struct f01_device_status *status)
-{
- int retval;
-
- retval = fwu->fn_ptr->read(fwu->rmi4_data,
- fwu->f01_fd.data_base_addr,
- status->data,
- sizeof(status->data));
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to read F01 device status\n",
- __func__);
- return retval;
- }
-
- return 0;
-}
-
-static int fwu_read_f34_queries(void)
-{
- int retval;
- unsigned char count = 4;
- unsigned char buf[10];
- struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
-
- retval = fwu->fn_ptr->read(fwu->rmi4_data,
- fwu->f34_fd.query_base_addr + BOOTLOADER_ID_OFFSET,
- fwu->bootloader_id,
- sizeof(fwu->bootloader_id));
- if (retval < 0) {
- dev_err(&i2c_client->dev,
- "%s: Failed to read bootloader ID\n",
- __func__);
- return retval;
- }
-
- retval = fwu->fn_ptr->read(fwu->rmi4_data,
- fwu->f34_fd.query_base_addr + FLASH_PROPERTIES_OFFSET,
- fwu->flash_properties.data,
- sizeof(fwu->flash_properties.data));
- if (retval < 0) {
- dev_err(&i2c_client->dev,
- "%s: Failed to read flash properties\n",
- __func__);
- return retval;
- }
-
- dev_info(&i2c_client->dev, "%s perm:%d, bl:%d, display:%d\n",
- __func__,
- fwu->flash_properties.has_perm_config,
- fwu->flash_properties.has_bl_config,
- fwu->flash_properties.has_display_config);
-
- if (fwu->flash_properties.has_perm_config)
- count += 2;
-
- if (fwu->flash_properties.has_bl_config)
- count += 2;
-
- if (fwu->flash_properties.has_display_config)
- count += 2;
-
- retval = fwu->fn_ptr->read(fwu->rmi4_data,
- fwu->f34_fd.query_base_addr + BLOCK_SIZE_OFFSET,
- buf,
- 2);
- if (retval < 0) {
- dev_err(&i2c_client->dev,
- "%s: Failed to read block size info\n",
- __func__);
- return retval;
- }
-
- batohs(&fwu->block_size, &(buf[0]));
-
- retval = fwu->fn_ptr->read(fwu->rmi4_data,
- fwu->f34_fd.query_base_addr + FW_BLOCK_COUNT_OFFSET,
- buf,
- count);
- if (retval < 0) {
- dev_err(&i2c_client->dev,
- "%s: Failed to read block count info\n",
- __func__);
- return retval;
- }
-
- batohs(&fwu->fw_block_count, &(buf[0]));
- batohs(&fwu->config_block_count, &(buf[2]));
-
- count = 4;
-
- if (fwu->flash_properties.has_perm_config) {
- batohs(&fwu->perm_config_block_count, &(buf[count]));
- count += 2;
- }
-
- if (fwu->flash_properties.has_bl_config) {
- batohs(&fwu->bl_config_block_count, &(buf[count]));
- count += 2;
- }
-
- if (fwu->flash_properties.has_display_config)
- batohs(&fwu->disp_config_block_count, &(buf[count]));
-
- fwu->addr_f34_flash_control = fwu->f34_fd.data_base_addr +
- BLOCK_DATA_OFFSET +
- fwu->block_size;
- return 0;
-}
-
-static int fwu_read_interrupt_status(void)
-{
- int retval;
- unsigned char interrupt_status;
- retval = fwu->fn_ptr->read(fwu->rmi4_data,
- fwu->addr_f01_interrupt_register,
- &interrupt_status,
- sizeof(interrupt_status));
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to read flash status\n",
- __func__);
- return retval;
- }
- return interrupt_status;
-}
-
-static int fwu_read_f34_flash_status(void)
-{
- int retval;
- retval = fwu->fn_ptr->read(fwu->rmi4_data,
- fwu->addr_f34_flash_control,
- fwu->flash_control.data,
- sizeof(fwu->flash_control.data));
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to read flash status\n",
- __func__);
- return retval;
- }
- return 0;
-}
-
-static int fwu_reset_device(void)
-{
- int retval;
-
-#ifdef DEBUG_FW_UPDATE
- dev_info(&fwu->rmi4_data->i2c_client->dev,
- "%s: Reset device\n",
- __func__);
-#endif
-
- retval = fwu->rmi4_data->reset_device(fwu->rmi4_data);
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to reset core driver after reflash\n",
- __func__);
- return retval;
- }
- return 0;
-}
-
-static int fwu_write_f34_command(unsigned char cmd)
-{
- int retval;
-
- fwu->flash_control.data[0] = cmd;
- retval = fwu->fn_ptr->write(fwu->rmi4_data,
- fwu->addr_f34_flash_control,
- fwu->flash_control.data,
- sizeof(fwu->flash_control.data));
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to write command 0x%02x\n",
- __func__, fwu->flash_control.data[0]);
- return retval;
- }
- return 0;
-}
-
-static int fwu_wait_for_idle(int timeout_ms)
-{
- int count = 0;
- int timeout_count = ((timeout_ms * 1000) / SLEEP_TIME_US) + 1;
- do {
- if (fwu->flash_control.command == 0x00)
- return 0;
-
- usleep_range(SLEEP_TIME_US, SLEEP_TIME_US + 100);
- } while (count++ < timeout_count);
-
- fwu_read_f34_flash_status();
- if (fwu->flash_control.command == 0x00)
- return 0;
-
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Timed out waiting for idle status\n",
- __func__);
-
- return -ETIMEDOUT;
-}
-
-static enum flash_area fwu_go_nogo(void)
-{
- int retval = 0;
- int index = 0;
- int deviceFirmwareID;
- int imageConfigID;
- int deviceConfigID;
- unsigned long imageFirmwareID;
- unsigned char firmware_id[4];
- unsigned char config_id[4];
- char *strptr;
- char *imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL);
- enum flash_area flash_area = NONE;
- struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
- struct f01_device_status f01_device_status;
-
- if (fwu->force_update) {
- flash_area = UI_FIRMWARE;
- goto exit;
- }
-
- retval = fwu_read_f01_device_status(&f01_device_status);
- if (retval < 0) {
- flash_area = NONE;
- goto exit;
- }
-
- imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL);
-
- /* Force update firmware when device is in bootloader mode */
- if (f01_device_status.flash_prog) {
- dev_info(&i2c_client->dev,
- "%s: In flash prog mode\n",
- __func__);
- flash_area = UI_FIRMWARE;
- goto exit;
- }
-
-
- /* device firmware id */
- retval = fwu->fn_ptr->read(fwu->rmi4_data,
- fwu->f01_fd.query_base_addr + 18,
- firmware_id,
- sizeof(firmware_id));
- if (retval < 0) {
- dev_err(&i2c_client->dev,
- "Failed to read firmware ID (code %d).\n", retval);
- goto exit;
- }
- firmware_id[3] = 0;
- deviceFirmwareID = extract_uint(firmware_id);
-
- /* .img firmware id */
- strptr = strstr(FW_IMAGE_NAME, "PR");
- if (!strptr) {
- dev_err(&i2c_client->dev,
- "No valid PR number (PRxxxxxxx)" \
- "found in image file name...\n");
- goto exit;
- }
-
- strptr += 2;
- while (strptr[index] >= '0' && strptr[index] <= '9') {
- imagePR[index] = strptr[index];
- index++;
- }
- imagePR[index] = 0;
-
- retval = sstrtoul(imagePR, 10, &imageFirmwareID);
- if (retval == -EINVAL) {
- dev_err(&i2c_client->dev,
- "invalid image firmware id...\n");
- goto exit;
- }
-
- dev_info(&i2c_client->dev,
- "Device firmware id %d, .img firmware id %d\n",
- deviceFirmwareID,
- (unsigned int)imageFirmwareID);
- if (imageFirmwareID > deviceFirmwareID) {
- flash_area = UI_FIRMWARE;
- goto exit;
- }
-
- /* device config id */
- retval = fwu->fn_ptr->read(fwu->rmi4_data,
- fwu->f34_fd.ctrl_base_addr,
- config_id,
- sizeof(config_id));
- if (retval < 0) {
- dev_err(&i2c_client->dev,
- "Failed to read config ID (code %d).\n", retval);
- flash_area = NONE;
- goto exit;
- }
- deviceConfigID = extract_uint(config_id);
-
- dev_info(&i2c_client->dev,
- "Device config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
- config_id[0], config_id[1], config_id[2], config_id[3]);
-
- /* .img config id */
- dev_info(&i2c_client->dev,
- ".img config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
- fwu->config_data[0],
- fwu->config_data[1],
- fwu->config_data[2],
- fwu->config_data[3]);
- imageConfigID = extract_uint(fwu->config_data);
-
- if (imageConfigID > deviceConfigID) {
- flash_area = CONFIG_AREA;
- goto exit;
- }
-
-exit:
- kfree(imagePR);
- if (flash_area == NONE)
- dev_info(&i2c_client->dev,
- "Nothing needs to be updated\n");
- else
- dev_info(&i2c_client->dev,
- "Update %s block\n",
- flash_area == UI_FIRMWARE ? "UI FW" : "CONFIG");
- return flash_area;
-}
-
-static int fwu_scan_pdt(void)
-{
- int retval;
- unsigned char ii;
- unsigned char intr_count = 0;
- unsigned char intr_off;
- unsigned char intr_src;
- unsigned short addr;
- bool f01found = false;
- bool f34found = false;
- struct synaptics_rmi4_fn_desc rmi_fd;
-
-#ifdef DEBUG_FW_UPDATE
- dev_info(&fwu->rmi4_data->i2c_client->dev, "Scan PDT\n");
-#endif
-
- for (addr = PDT_START; addr > PDT_END; addr -= PDT_ENTRY_SIZE) {
- retval = fwu->fn_ptr->read(fwu->rmi4_data,
- addr,
- (unsigned char *)&rmi_fd,
- sizeof(rmi_fd));
- if (retval < 0)
- return retval;
-
- if (rmi_fd.fn_number) {
- dev_dbg(&fwu->rmi4_data->i2c_client->dev,
- "%s: Found F%02x\n",
- __func__, rmi_fd.fn_number);
- switch (rmi_fd.fn_number) {
- case SYNAPTICS_RMI4_F01:
- f01found = true;
- fwu->f01_fd = rmi_fd;
- fwu->addr_f01_interrupt_register =
- fwu->f01_fd.data_base_addr + 1;
- break;
- case SYNAPTICS_RMI4_F34:
- f34found = true;
- fwu->f34_fd = rmi_fd;
- fwu->intr_mask = 0;
- intr_src = rmi_fd.intr_src_count;
- intr_off = intr_count % 8;
- for (ii = intr_off;
- ii < ((intr_src & MASK_3BIT) +
- intr_off);
- ii++)
- fwu->intr_mask |= 1 << ii;
- break;
- }
- } else
- break;
-
- intr_count += (rmi_fd.intr_src_count & MASK_3BIT);
- }
-
- if (!f01found || !f34found) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to find both F01 and F34\n",
- __func__);
- return -EINVAL;
- }
-
- fwu_read_interrupt_status();
- return 0;
-}
-
-static int fwu_write_blocks(unsigned char *block_ptr, unsigned short block_cnt,
- unsigned char command)
-{
- int retval;
- unsigned char block_offset[] = {0, 0};
- unsigned short block_num;
- struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
-#ifdef SHOW_PROGRESS
- unsigned int progress = (command == CMD_WRITE_CONFIG_BLOCK) ?
- 10 : 100;
-#endif
-
-#ifdef DEBUG_FW_UPDATE
- dev_info(&i2c_client->dev,
- "%s: Start to update %s blocks\n",
- __func__,
- command == CMD_WRITE_CONFIG_BLOCK ?
- "config" : "firmware");
-#endif
- retval = fwu->fn_ptr->write(fwu->rmi4_data,
- fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET,
- block_offset,
- sizeof(block_offset));
- if (retval < 0) {
- dev_err(&i2c_client->dev,
- "%s: Failed to write to block number registers\n",
- __func__);
- return retval;
- }
-
- for (block_num = 0; block_num < block_cnt; block_num++) {
-#ifdef SHOW_PROGRESS
- if (block_num % progress == 0)
- dev_info(&i2c_client->dev,
- "%s: update %s %3d / %3d\n",
- __func__,
- command == CMD_WRITE_CONFIG_BLOCK ?
- "config" : "firmware",
- block_num, block_cnt);
-#endif
- retval = fwu->fn_ptr->write(fwu->rmi4_data,
- fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
- block_ptr,
- fwu->block_size);
- if (retval < 0) {
- dev_err(&i2c_client->dev,
- "%s: Failed to write block data (block %d)\n",
- __func__, block_num);
- return retval;
- }
-
- retval = fwu_write_f34_command(command);
- if (retval < 0) {
- dev_err(&i2c_client->dev,
- "%s: Failed to write command for block %d\n",
- __func__, block_num);
- return retval;
- }
-
- retval = fwu_wait_for_idle(WRITE_WAIT_MS);
- if (retval < 0) {
- dev_err(&i2c_client->dev,
- "%s: Failed to wait for idle status (block %d)\n",
- __func__, block_num);
- return retval;
- }
-
- if (fwu->flash_control.status != 0x00) {
- dev_err(&i2c_client->dev,
- "%s: Flash block %d failed, status 0x%02X\n",
- __func__, block_num, retval);
- return -1;
- }
-
- block_ptr += fwu->block_size;
- }
-#ifdef SHOW_PROGRESS
- dev_info(&i2c_client->dev,
- "%s: update %s %3d / %3d\n",
- __func__,
- command == CMD_WRITE_CONFIG_BLOCK ?
- "config" : "firmware",
- block_cnt, block_cnt);
-#endif
- return 0;
-}
-
-static int fwu_write_firmware(void)
-{
- return fwu_write_blocks((unsigned char *)fwu->firmware_data,
- fwu->fw_block_count, CMD_WRITE_FW_BLOCK);
-}
-
-static int fwu_write_configuration(void)
-{
- return fwu_write_blocks((unsigned char *)fwu->config_data,
- fwu->config_block_count, CMD_WRITE_CONFIG_BLOCK);
-}
-
-static int fwu_write_bootloader_id(void)
-{
- int retval;
-
-#ifdef DEBUG_FW_UPDATE
- dev_info(&fwu->rmi4_data->i2c_client->dev,
- "Write bootloader ID 0x%02X 0x%02X\n",
- fwu->bootloader_id[0],
- fwu->bootloader_id[1]);
-#endif
- retval = fwu->fn_ptr->write(fwu->rmi4_data,
- fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
- fwu->bootloader_id,
- sizeof(fwu->bootloader_id));
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to write bootloader ID\n",
- __func__);
- return retval;
- }
-
- return 0;
-}
-
-static int fwu_enter_flash_prog(void)
-{
- int retval;
- struct f01_device_status f01_device_status;
- struct f01_device_control f01_device_control;
-
-#ifdef DEBUG_FW_UPDATE
- dev_info(&fwu->rmi4_data->i2c_client->dev, "Enter bootloader mode\n");
-#endif
- retval = fwu_read_f01_device_status(&f01_device_status);
- if (retval < 0)
- return retval;
-
- if (f01_device_status.flash_prog) {
- dev_info(&fwu->rmi4_data->i2c_client->dev,
- "%s: Already in flash prog mode\n",
- __func__);
- return 0;
- }
-
- retval = fwu_write_bootloader_id();
- if (retval < 0)
- return retval;
-
- retval = fwu_write_f34_command(CMD_ENABLE_FLASH_PROG);
- if (retval < 0)
- return retval;
-
- retval = fwu_wait_for_idle(ENABLE_WAIT_MS);
- if (retval < 0)
- return retval;
-
- retval = fwu_scan_pdt();
- if (retval < 0)
- return retval;
-
- retval = fwu_read_f01_device_status(&f01_device_status);
- if (retval < 0)
- return retval;
-
- if (!f01_device_status.flash_prog) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Not in flash prog mode\n",
- __func__);
- return -EINVAL;
- }
-
- retval = fwu_read_f34_queries();
- if (retval < 0)
- return retval;
-
- retval = fwu->fn_ptr->read(fwu->rmi4_data,
- fwu->f01_fd.ctrl_base_addr,
- f01_device_control.data,
- sizeof(f01_device_control.data));
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to read F01 device control\n",
- __func__);
- return retval;
- }
-
- f01_device_control.nosleep = true;
- f01_device_control.sleep_mode = SLEEP_MODE_NORMAL;
-
- retval = fwu->fn_ptr->write(fwu->rmi4_data,
- fwu->f01_fd.ctrl_base_addr,
- f01_device_control.data,
- sizeof(f01_device_control.data));
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to write F01 device control\n",
- __func__);
- return retval;
- }
-
- return retval;
-}
-
-static int fwu_do_reflash(void)
-{
- int retval;
-
- retval = fwu_enter_flash_prog();
- if (retval < 0)
- return retval;
-
- dev_dbg(&fwu->rmi4_data->i2c_client->dev,
- "%s: Entered flash prog mode\n",
- __func__);
-
- retval = fwu_write_bootloader_id();
- if (retval < 0)
- return retval;
-
- dev_dbg(&fwu->rmi4_data->i2c_client->dev,
- "%s: Bootloader ID written\n",
- __func__);
-
- retval = fwu_write_f34_command(CMD_ERASE_ALL);
- if (retval < 0)
- return retval;
-
- dev_dbg(&fwu->rmi4_data->i2c_client->dev,
- "%s: Erase all command written\n",
- __func__);
-
- retval = fwu_wait_for_idle(ERASE_WAIT_MS);
- if (retval < 0)
- return retval;
-
- if (fwu->flash_control.status != 0x00) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Erase all command failed, status 0x%02X\n",
- __func__, retval);
- return -1;
- }
-
- if (fwu->firmware_data) {
- retval = fwu_write_firmware();
- if (retval < 0)
- return retval;
- pr_notice("%s: Firmware programmed\n", __func__);
- }
-
- if (fwu->config_data) {
- retval = fwu_write_configuration();
- if (retval < 0)
- return retval;
- pr_notice("%s: Configuration programmed\n", __func__);
- }
-
- return retval;
-}
-
-static int fwu_do_write_config(void)
-{
- int retval;
-
- retval = fwu_enter_flash_prog();
- if (retval < 0)
- return retval;
-
- dev_dbg(&fwu->rmi4_data->i2c_client->dev,
- "%s: Entered flash prog mode\n",
- __func__);
-
- if (fwu->config_area == PERM_CONFIG_AREA) {
- fwu->config_block_count = fwu->perm_config_block_count;
- goto write_config;
- }
-
- retval = fwu_write_bootloader_id();
- if (retval < 0)
- return retval;
-
- dev_dbg(&fwu->rmi4_data->i2c_client->dev,
- "%s: Bootloader ID written\n",
- __func__);
-
- switch (fwu->config_area) {
- case UI_CONFIG_AREA:
- retval = fwu_write_f34_command(CMD_ERASE_CONFIG);
- break;
- case BL_CONFIG_AREA:
- retval = fwu_write_f34_command(CMD_ERASE_BL_CONFIG);
- fwu->config_block_count = fwu->bl_config_block_count;
- break;
- case DISP_CONFIG_AREA:
- retval = fwu_write_f34_command(CMD_ERASE_DISP_CONFIG);
- fwu->config_block_count = fwu->disp_config_block_count;
- break;
- }
- if (retval < 0)
- return retval;
-
- dev_dbg(&fwu->rmi4_data->i2c_client->dev,
- "%s: Erase command written\n",
- __func__);
-
- retval = fwu_wait_for_idle(ERASE_WAIT_MS);
- if (retval < 0)
- return retval;
-
- dev_dbg(&fwu->rmi4_data->i2c_client->dev,
- "%s: Idle status detected\n",
- __func__);
-
-write_config:
- retval = fwu_write_configuration();
- if (retval < 0)
- return retval;
-
- pr_notice("%s: Config written\n", __func__);
-
- return retval;
-}
-
-static int fwu_start_write_config(void)
-{
- int retval;
- struct image_header header;
-
- switch (fwu->config_area) {
- case UI_CONFIG_AREA:
- break;
- case PERM_CONFIG_AREA:
- if (!fwu->flash_properties.has_perm_config)
- return -EINVAL;
- break;
- case BL_CONFIG_AREA:
- if (!fwu->flash_properties.has_bl_config)
- return -EINVAL;
- break;
- case DISP_CONFIG_AREA:
- if (!fwu->flash_properties.has_display_config)
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
-
- if (fwu->ext_data_source)
- fwu->config_data = fwu->ext_data_source;
- else
- return -EINVAL;
-
- if (fwu->config_area == UI_CONFIG_AREA) {
- parse_header(&header, fwu->ext_data_source);
-
- if (header.config_size) {
- fwu->config_data = fwu->ext_data_source +
- FW_IMAGE_OFFSET +
- header.image_size;
- } else {
- return -EINVAL;
- }
- }
-
- pr_notice("%s: Start of write config process\n", __func__);
-
- retval = fwu_do_write_config();
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to write config\n",
- __func__);
- }
-
- fwu->rmi4_data->reset_device(fwu->rmi4_data);
-
- pr_notice("%s: End of write config process\n", __func__);
-
- return retval;
-}
-
-static int fwu_do_read_config(void)
-{
- int retval;
- unsigned char block_offset[] = {0, 0};
- unsigned short block_num;
- unsigned short block_count;
- unsigned short index = 0;
-
- retval = fwu_enter_flash_prog();
- if (retval < 0)
- goto exit;
-
- dev_dbg(&fwu->rmi4_data->i2c_client->dev,
- "%s: Entered flash prog mode\n",
- __func__);
-
- switch (fwu->config_area) {
- case UI_CONFIG_AREA:
- block_count = fwu->config_block_count;
- break;
- case PERM_CONFIG_AREA:
- if (!fwu->flash_properties.has_perm_config) {
- retval = -EINVAL;
- goto exit;
- }
- block_count = fwu->perm_config_block_count;
- break;
- case BL_CONFIG_AREA:
- if (!fwu->flash_properties.has_bl_config) {
- retval = -EINVAL;
- goto exit;
- }
- block_count = fwu->bl_config_block_count;
- break;
- case DISP_CONFIG_AREA:
- if (!fwu->flash_properties.has_display_config) {
- retval = -EINVAL;
- goto exit;
- }
- block_count = fwu->disp_config_block_count;
- break;
- default:
- retval = -EINVAL;
- goto exit;
- }
-
- fwu->config_size = fwu->block_size * block_count;
-
- kfree(fwu->read_config_buf);
- fwu->read_config_buf = kzalloc(fwu->config_size, GFP_KERNEL);
-
- block_offset[1] |= (fwu->config_area << 5);
-
- retval = fwu->fn_ptr->write(fwu->rmi4_data,
- fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET,
- block_offset,
- sizeof(block_offset));
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to write to block number registers\n",
- __func__);
- goto exit;
- }
-
- for (block_num = 0; block_num < block_count; block_num++) {
- retval = fwu_write_f34_command(CMD_READ_CONFIG_BLOCK);
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to write read config command\n",
- __func__);
- goto exit;
- }
-
- retval = fwu_wait_for_idle(WRITE_WAIT_MS);
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to wait for idle status\n",
- __func__);
- goto exit;
- }
-
- retval = fwu->fn_ptr->read(fwu->rmi4_data,
- fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
- &fwu->read_config_buf[index],
- fwu->block_size);
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to read block data (block %d)\n",
- __func__, block_num);
- goto exit;
- }
-
- index += fwu->block_size;
- }
-
-exit:
- fwu->rmi4_data->reset_device(fwu->rmi4_data);
-
- return retval;
-}
-
-static int fwu_start_reflash(void)
-{
- int retval;
- struct image_header header;
- const unsigned char *fw_image;
- const struct firmware *fw_entry = NULL;
- struct f01_device_status f01_device_status;
- enum flash_area flash_area;
-
- pr_notice("%s: Start of reflash process\n", __func__);
-
- if (fwu->ext_data_source)
- fw_image = fwu->ext_data_source;
- else {
- dev_dbg(&fwu->rmi4_data->i2c_client->dev,
- "%s: Requesting firmware image %s\n",
- __func__, FW_IMAGE_NAME);
-
- retval = request_firmware(&fw_entry, FW_IMAGE_NAME,
- &fwu->rmi4_data->i2c_client->dev);
- if (retval != 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Firmware image %s not available\n",
- __func__, FW_IMAGE_NAME);
- retval = -EINVAL;
- goto exit;
- }
-
- dev_dbg(&fwu->rmi4_data->i2c_client->dev,
- "%s: Firmware image size = %d\n",
- __func__, fw_entry->size);
-
- fw_image = fw_entry->data;
- }
-
- parse_header(&header, fw_image);
-
- if (header.image_size)
- fwu->firmware_data = fw_image + FW_IMAGE_OFFSET;
- if (header.config_size) {
- fwu->config_data = fw_image + FW_IMAGE_OFFSET +
- header.image_size;
- }
-
- if (fwu->ext_data_source)
- flash_area = UI_FIRMWARE;
- else
- flash_area = fwu_go_nogo();
-
- switch (flash_area) {
- case NONE:
- dev_info(&fwu->rmi4_data->i2c_client->dev,
- "%s: No need to do reflash.\n",
- __func__);
- goto exit;
- case UI_FIRMWARE:
- retval = fwu_do_reflash();
- break;
- case CONFIG_AREA:
- retval = fwu_do_write_config();
- break;
- default:
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Unknown flash area\n",
- __func__);
- goto exit;
- }
-
- if (retval < 0) {
- dev_err(&fwu->rmi4_data->i2c_client->dev,
- "%s: Failed to do reflash\n",
- __func__);
- }
-
- /* reset device */
- fwu_reset_device();
-
- /* check device status */
- retval = fwu_read_f01_device_status(&f01_device_status);
- if (retval < 0)
- goto exit;
-
- dev_info(&fwu->rmi4_data->i2c_client->dev, "Device is in %s mode\n",
- f01_device_status.flash_prog == 1 ? "bootloader" : "UI");
- if (f01_device_status.flash_prog)
- dev_info(&fwu->rmi4_data->i2c_client->dev, "Flash status %d\n",
- f01_device_status.status_code);
-
- if (f01_device_status.flash_prog) {
- dev_info(&fwu->rmi4_data->i2c_client->dev,
- "%s: Device is in flash prog mode 0x%02X\n",
- __func__, f01_device_status.status_code);
- retval = 0;
- goto exit;
- }
-
- if (fw_entry)
- release_firmware(fw_entry);
-
- pr_notice("%s: End of reflash process\n", __func__);
-exit:
- return retval;
-}
-
-int synaptics_fw_updater(unsigned char *fw_data)
-{
- int retval;
-
- if (!fwu)
- return -ENODEV;
-
- if (!fwu->initialized)
- return -ENODEV;
-
- fwu->ext_data_source = fw_data;
- fwu->config_area = UI_CONFIG_AREA;
-
- retval = fwu_start_reflash();
-
- return retval;
-}
-EXPORT_SYMBOL(synaptics_fw_updater);
-
-static ssize_t fwu_sysfs_show_image(struct file *data_file,
- struct kobject *kobj, struct bin_attribute *attributes,
- char *buf, loff_t pos, size_t count)
-{
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
-
- if (count < fwu->config_size) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Not enough space (%d bytes) in buffer\n",
- __func__, count);
- return -EINVAL;
- }
-
- memcpy(buf, fwu->read_config_buf, fwu->config_size);
-
- return fwu->config_size;
-}
-
-static ssize_t fwu_sysfs_store_image(struct file *data_file,
- struct kobject *kobj, struct bin_attribute *attributes,
- char *buf, loff_t pos, size_t count)
-{
- memcpy((void *)(&fwu->ext_data_source[fwu->data_pos]),
- (const void *)buf,
- count);
-
- fwu->data_pos += count;
-
- return count;
-}
-
-static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int retval;
- unsigned int input;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
-
- if (sscanf(buf, "%u", &input) != 1) {
- retval = -EINVAL;
- goto exit;
- }
-
- if (input != 1) {
- retval = -EINVAL;
- goto exit;
- }
-
- retval = synaptics_fw_updater(fwu->ext_data_source);
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to do reflash\n",
- __func__);
- goto exit;
- }
-
- retval = count;
-
-exit:
- kfree(fwu->ext_data_source);
- fwu->ext_data_source = NULL;
- return retval;
-}
-
-static ssize_t fwu_sysfs_write_config_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int retval;
- unsigned int input;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
-
- if (sscanf(buf, "%u", &input) != 1) {
- retval = -EINVAL;
- goto exit;
- }
-
- if (input != 1) {
- retval = -EINVAL;
- goto exit;
- }
-
- retval = fwu_start_write_config();
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to write config\n",
- __func__);
- goto exit;
- }
-
- retval = count;
-
-exit:
- kfree(fwu->ext_data_source);
- fwu->ext_data_source = NULL;
- return retval;
-}
-
-static ssize_t fwu_sysfs_read_config_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int retval;
- unsigned int input;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
-
- if (sscanf(buf, "%u", &input) != 1)
- return -EINVAL;
-
- if (input != 1)
- return -EINVAL;
-
- retval = fwu_do_read_config();
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to read config\n",
- __func__);
- return retval;
- }
-
- return count;
-}
-
-static ssize_t fwu_sysfs_config_area_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int retval;
- unsigned long config_area;
-
- retval = sstrtoul(buf, 10, &config_area);
- if (retval)
- return retval;
-
- fwu->config_area = config_area;
-
- return count;
-}
-
-static ssize_t fwu_sysfs_image_size_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int retval;
- unsigned long size;
- struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
-
- retval = sstrtoul(buf, 10, &size);
- if (retval)
- return retval;
-
- fwu->image_size = size;
- fwu->data_pos = 0;
-
- kfree(fwu->ext_data_source);
- fwu->ext_data_source = kzalloc(fwu->image_size, GFP_KERNEL);
- if (!fwu->ext_data_source) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to alloc mem for image data\n",
- __func__);
- return -ENOMEM;
- }
-
- return count;
-}
-
-static ssize_t fwu_sysfs_block_size_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%u\n", fwu->block_size);
-}
-
-static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%u\n", fwu->fw_block_count);
-}
-
-static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%u\n", fwu->config_block_count);
-}
-
-static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%u\n", fwu->perm_config_block_count);
-}
-
-static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%u\n", fwu->bl_config_block_count);
-}
-
-static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%u\n", fwu->disp_config_block_count);
-}
-
-static void synaptics_rmi4_fwu_attn(struct synaptics_rmi4_data *rmi4_data,
- unsigned char intr_mask)
-{
- if (fwu->intr_mask & intr_mask)
- fwu_read_f34_flash_status();
-
- return;
-}
-
-static void synaptics_rmi4_fwu_work(struct work_struct *work)
-{
- fwu_start_reflash();
-}
-
-static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
-{
- int retval;
- unsigned char attr_count;
- struct pdt_properties pdt_props;
-
- fwu = kzalloc(sizeof(*fwu), GFP_KERNEL);
- if (!fwu) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to alloc mem for fwu\n",
- __func__);
- goto exit;
- }
-
- fwu->fn_ptr = kzalloc(sizeof(*(fwu->fn_ptr)), GFP_KERNEL);
- if (!fwu->fn_ptr) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to alloc mem for fn_ptr\n",
- __func__);
- retval = -ENOMEM;
- goto exit_free_fwu;
- }
-
- fwu->rmi4_data = rmi4_data;
- fwu->fn_ptr->read = rmi4_data->i2c_read;
- fwu->fn_ptr->write = rmi4_data->i2c_write;
- fwu->fn_ptr->enable = rmi4_data->irq_enable;
-
- retval = fwu->fn_ptr->read(rmi4_data,
- PDT_PROPS,
- pdt_props.data,
- sizeof(pdt_props.data));
- if (retval < 0) {
- dev_dbg(&rmi4_data->i2c_client->dev,
- "%s: Failed to read PDT properties, assuming 0x00\n",
- __func__);
- } else if (pdt_props.has_bsr) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Reflash for LTS not currently supported\n",
- __func__);
- goto exit_free_mem;
- }
-
- retval = fwu_scan_pdt();
- if (retval < 0)
- goto exit_free_mem;
-
- fwu->productinfo1 = rmi4_data->rmi4_mod_info.product_info[0];
- fwu->productinfo2 = rmi4_data->rmi4_mod_info.product_info[1];
-
- memcpy(fwu->product_id, rmi4_data->rmi4_mod_info.product_id_string,
- SYNAPTICS_RMI4_PRODUCT_ID_SIZE);
- fwu->product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE] = 0;
-
- dev_dbg(&rmi4_data->i2c_client->dev,
- "%s: F01 product info: 0x%04x 0x%04x\n",
- __func__, fwu->productinfo1, fwu->productinfo2);
- dev_dbg(&rmi4_data->i2c_client->dev,
- "%s: F01 product ID: %s\n",
- __func__, fwu->product_id);
-
- retval = fwu_read_f34_queries();
- if (retval < 0)
- goto exit_free_mem;
-
- fwu->initialized = true;
- fwu->force_update = FORCE_UPDATE;
-
- retval = sysfs_create_bin_file(&rmi4_data->input_dev->dev.kobj,
- &dev_attr_data);
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to create sysfs bin file\n",
- __func__);
- goto exit_free_mem;
- }
-
- for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
- retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj,
- &attrs[attr_count].attr);
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to create sysfs attributes\n",
- __func__);
- retval = -ENODEV;
- goto exit_remove_attrs;
- }
- }
-
-#ifdef INSIDE_FIRMWARE_UPDATE
- fwu->fwu_workqueue = create_singlethread_workqueue("fwu_workqueue");
- INIT_DELAYED_WORK(&fwu->fwu_work, synaptics_rmi4_fwu_work);
- queue_delayed_work(fwu->fwu_workqueue,
- &fwu->fwu_work,
- msecs_to_jiffies(1000));
-#endif
- return 0;
-
-exit_remove_attrs:
-for (attr_count--; attr_count >= 0; attr_count--) {
- sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
- &attrs[attr_count].attr);
-}
-
-sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
-
-exit_free_mem:
- kfree(fwu->fn_ptr);
-
-exit_free_fwu:
- kfree(fwu);
-
-exit:
- return 0;
-}
-
-static void synaptics_rmi4_fwu_remove(struct synaptics_rmi4_data *rmi4_data)
-{
- unsigned char attr_count;
-
- sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
-
- for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
- sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
- &attrs[attr_count].attr);
- }
-
- kfree(fwu->fn_ptr);
- kfree(fwu);
-
- complete(&remove_complete);
-
- return;
-}
-
-static int __init rmi4_fw_update_module_init(void)
-{
- synaptics_rmi4_new_function(RMI_FW_UPDATER, true,
- synaptics_rmi4_fwu_init,
- synaptics_rmi4_fwu_remove,
- synaptics_rmi4_fwu_attn);
- return 0;
-}
-
-static void __exit rmi4_fw_update_module_exit(void)
-{
- init_completion(&remove_complete);
- synaptics_rmi4_new_function(RMI_FW_UPDATER, false,
- synaptics_rmi4_fwu_init,
- synaptics_rmi4_fwu_remove,
- synaptics_rmi4_fwu_attn);
- wait_for_completion(&remove_complete);
- return;
-}
-
-module_init(rmi4_fw_update_module_init);
-module_exit(rmi4_fw_update_module_exit);
-
-MODULE_AUTHOR("Synaptics, Inc.");
-MODULE_DESCRIPTION("RMI4 FW Update Module");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(SYNAPTICS_RMI4_DRIVER_VERSION);
diff --git a/kernel/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/kernel/drivers/input/touchscreen/synaptics_i2c_rmi4.c
deleted file mode 100644
index 76f9155bd49c..000000000000
--- a/kernel/drivers/input/touchscreen/synaptics_i2c_rmi4.c
+++ /dev/null
@@ -1,2162 +0,0 @@
-/*
- * Synaptics RMI4 touchscreen driver
- *
- * Copyright (C) 2012 Synaptics Incorporated
- *
- * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
- * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/input.h>
-#include <linux/gpio.h>
-#include <linux/regulator/consumer.h>
-#include <linux/input/synaptics_dsx.h>
-#include "synaptics_i2c_rmi4.h"
-#ifdef KERNEL_ABOVE_2_6_38
-#include <linux/input/mt.h>
-#endif
-
-#define DRIVER_NAME "synaptics_rmi4_i2c"
-#define INPUT_PHYS_NAME "synaptics_rmi4_i2c/input0"
-
-#ifdef KERNEL_ABOVE_2_6_38
-#define TYPE_B_PROTOCOL
-#endif
-
-#define NO_0D_WHILE_2D
-/*
-#define REPORT_2D_Z
-*/
-#define REPORT_2D_W
-
-#define RPT_TYPE (1 << 0)
-#define RPT_X_LSB (1 << 1)
-#define RPT_X_MSB (1 << 2)
-#define RPT_Y_LSB (1 << 3)
-#define RPT_Y_MSB (1 << 4)
-#define RPT_Z (1 << 5)
-#define RPT_WX (1 << 6)
-#define RPT_WY (1 << 7)
-#define RPT_DEFAULT (RPT_TYPE | RPT_X_LSB | RPT_X_MSB | RPT_Y_LSB | RPT_Y_MSB)
-
-#define EXP_FN_DET_INTERVAL 1000 /* ms */
-#define POLLING_PERIOD 1 /* ms */
-#define SYN_I2C_RETRY_TIMES 10
-#define MAX_ABS_MT_TOUCH_MAJOR 15
-
-#define F01_STD_QUERY_LEN 21
-#define F01_BUID_ID_OFFSET 18
-#define F11_STD_QUERY_LEN 9
-#define F11_STD_CTRL_LEN 10
-#define F11_STD_DATA_LEN 12
-
-#define NORMAL_OPERATION (0 << 0)
-#define SENSOR_SLEEP (1 << 0)
-#define NO_SLEEP_OFF (0 << 3)
-#define NO_SLEEP_ON (1 << 3)
-
-static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data,
- unsigned short addr, unsigned char *data,
- unsigned short length);
-
-static int synaptics_rmi4_i2c_write(struct synaptics_rmi4_data *rmi4_data,
- unsigned short addr, unsigned char *data,
- unsigned short length);
-
-static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data);
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static ssize_t synaptics_rmi4_full_pm_cycle_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t synaptics_rmi4_full_pm_cycle_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static void synaptics_rmi4_early_suspend(struct early_suspend *h);
-
-static void synaptics_rmi4_late_resume(struct early_suspend *h);
-
-static int synaptics_rmi4_suspend(struct device *dev);
-
-static int synaptics_rmi4_resume(struct device *dev);
-#endif
-
-static ssize_t synaptics_rmi4_f01_reset_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t synaptics_rmi4_f01_productinfo_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t synaptics_rmi4_f01_buildid_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t synaptics_rmi4_f01_flashprog_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t synaptics_rmi4_0dbutton_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-struct synaptics_rmi4_f01_device_status {
- union {
- struct {
- unsigned char status_code:4;
- unsigned char reserved:2;
- unsigned char flash_prog:1;
- unsigned char unconfigured:1;
- } __packed;
- unsigned char data[1];
- };
-};
-
-struct synaptics_rmi4_f1a_query {
- union {
- struct {
- unsigned char max_button_count:3;
- unsigned char reserved:5;
- unsigned char has_general_control:1;
- unsigned char has_interrupt_enable:1;
- unsigned char has_multibutton_select:1;
- unsigned char has_tx_rx_map:1;
- unsigned char has_perbutton_threshold:1;
- unsigned char has_release_threshold:1;
- unsigned char has_strongestbtn_hysteresis:1;
- unsigned char has_filter_strength:1;
- } __packed;
- unsigned char data[2];
- };
-};
-
-struct synaptics_rmi4_f1a_control_0 {
- union {
- struct {
- unsigned char multibutton_report:2;
- unsigned char filter_mode:2;
- unsigned char reserved:4;
- } __packed;
- unsigned char data[1];
- };
-};
-
-struct synaptics_rmi4_f1a_control_3_4 {
- unsigned char transmitterbutton;
- unsigned char receiverbutton;
-};
-
-struct synaptics_rmi4_f1a_control {
- struct synaptics_rmi4_f1a_control_0 general_control;
- unsigned char *button_int_enable;
- unsigned char *multi_button;
- struct synaptics_rmi4_f1a_control_3_4 *electrode_map;
- unsigned char *button_threshold;
- unsigned char button_release_threshold;
- unsigned char strongest_button_hysteresis;
- unsigned char filter_strength;
-};
-
-struct synaptics_rmi4_f1a_handle {
- int button_bitmask_size;
- unsigned char button_count;
- unsigned char valid_button_count;
- unsigned char *button_data_buffer;
- unsigned char *button_map;
- struct synaptics_rmi4_f1a_query button_query;
- struct synaptics_rmi4_f1a_control button_control;
-};
-
-struct synaptics_rmi4_exp_fn {
- enum exp_fn fn_type;
- bool inserted;
- int (*func_init)(struct synaptics_rmi4_data *rmi4_data);
- void (*func_remove)(struct synaptics_rmi4_data *rmi4_data);
- void (*func_attn)(struct synaptics_rmi4_data *rmi4_data,
- unsigned char intr_mask);
- struct list_head link;
-};
-
-static struct device_attribute attrs[] = {
-#ifdef CONFIG_HAS_EARLYSUSPEND
- __ATTR(full_pm_cycle, (S_IRUGO | S_IWUGO),
- synaptics_rmi4_full_pm_cycle_show,
- synaptics_rmi4_full_pm_cycle_store),
-#endif
- __ATTR(reset, S_IWUGO,
- synaptics_rmi4_show_error,
- synaptics_rmi4_f01_reset_store),
- __ATTR(productinfo, S_IRUGO,
- synaptics_rmi4_f01_productinfo_show,
- synaptics_rmi4_store_error),
- __ATTR(buildid, S_IRUGO,
- synaptics_rmi4_f01_buildid_show,
- synaptics_rmi4_store_error),
- __ATTR(flashprog, S_IRUGO,
- synaptics_rmi4_f01_flashprog_show,
- synaptics_rmi4_store_error),
- __ATTR(0dbutton, (S_IRUGO | S_IWUGO),
- synaptics_rmi4_0dbutton_show,
- synaptics_rmi4_0dbutton_store),
-};
-
-static bool exp_fn_inited;
-static struct mutex exp_fn_list_mutex;
-static struct list_head exp_fn_list;
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static ssize_t synaptics_rmi4_full_pm_cycle_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
-
- return snprintf(buf, PAGE_SIZE, "%u\n",
- rmi4_data->full_pm_cycle);
-}
-
-static ssize_t synaptics_rmi4_full_pm_cycle_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- unsigned int input;
- struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
-
- if (sscanf(buf, "%u", &input) != 1)
- return -EINVAL;
-
- rmi4_data->full_pm_cycle = input > 0 ? 1 : 0;
-
- return count;
-}
-#endif
-
-static ssize_t synaptics_rmi4_f01_reset_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int retval;
- unsigned int reset;
- struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
-
- if (sscanf(buf, "%u", &reset) != 1)
- return -EINVAL;
-
- if (reset != 1)
- return -EINVAL;
-
- retval = synaptics_rmi4_reset_device(rmi4_data);
- if (retval < 0) {
- dev_err(dev,
- "%s: Failed to issue reset command, error = %d\n",
- __func__, retval);
- return retval;
- }
-
- return count;
-}
-
-static ssize_t synaptics_rmi4_f01_productinfo_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
-
- return snprintf(buf, PAGE_SIZE, "0x%02x 0x%02x\n",
- (rmi4_data->rmi4_mod_info.product_info[0]),
- (rmi4_data->rmi4_mod_info.product_info[1]));
-}
-
-static ssize_t synaptics_rmi4_f01_buildid_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- unsigned int build_id;
- struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
- struct synaptics_rmi4_device_info *rmi;
-
- rmi = &(rmi4_data->rmi4_mod_info);
-
- build_id = (unsigned int)rmi->build_id[0] +
- (unsigned int)rmi->build_id[1] * 0x100 +
- (unsigned int)rmi->build_id[2] * 0x10000;
-
- return snprintf(buf, PAGE_SIZE, "%u\n",
- build_id);
-}
-
-static ssize_t synaptics_rmi4_f01_flashprog_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int retval;
- struct synaptics_rmi4_f01_device_status device_status;
- struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
-
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- rmi4_data->f01_data_base_addr,
- device_status.data,
- sizeof(device_status.data));
- if (retval < 0) {
- dev_err(dev,
- "%s: Failed to read device status, error = %d\n",
- __func__, retval);
- return retval;
- }
-
- return snprintf(buf, PAGE_SIZE, "%u\n",
- device_status.flash_prog);
-}
-
-static ssize_t synaptics_rmi4_0dbutton_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
-
- return snprintf(buf, PAGE_SIZE, "%u\n",
- rmi4_data->button_0d_enabled);
-}
-
-static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int retval;
- unsigned int input;
- unsigned char ii;
- unsigned char intr_enable;
- struct synaptics_rmi4_fn *fhandler;
- struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
- struct synaptics_rmi4_device_info *rmi;
-
- rmi = &(rmi4_data->rmi4_mod_info);
-
- if (sscanf(buf, "%u", &input) != 1)
- return -EINVAL;
-
- input = input > 0 ? 1 : 0;
-
- if (rmi4_data->button_0d_enabled == input)
- return count;
-
- if (!list_empty(&rmi->support_fn_list)) {
- list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
- if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) {
- ii = fhandler->intr_reg_num;
-
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- rmi4_data->f01_ctrl_base_addr +
- 1 + ii,
- &intr_enable,
- sizeof(intr_enable));
- if (retval < 0)
- return retval;
-
- if (input == 1)
- intr_enable |= fhandler->intr_mask;
- else
- intr_enable &= ~fhandler->intr_mask;
-
- retval = synaptics_rmi4_i2c_write(rmi4_data,
- rmi4_data->f01_ctrl_base_addr +
- 1 + ii,
- &intr_enable,
- sizeof(intr_enable));
- if (retval < 0)
- return retval;
- }
- }
- }
-
- rmi4_data->button_0d_enabled = input;
-
- return count;
-}
-
- /**
- * synaptics_rmi4_set_page()
- *
- * Called by synaptics_rmi4_i2c_read() and synaptics_rmi4_i2c_write().
- *
- * This function writes to the page select register to switch to the
- * assigned page.
- */
-static int synaptics_rmi4_set_page(struct synaptics_rmi4_data *rmi4_data,
- unsigned int address)
-{
- int retval = 0;
- unsigned char retry;
- unsigned char buf[PAGE_SELECT_LEN];
- unsigned char page;
- struct i2c_client *i2c = rmi4_data->i2c_client;
-
- page = ((address >> 8) & MASK_8BIT);
- if (page != rmi4_data->current_page) {
- buf[0] = MASK_8BIT;
- buf[1] = page;
- for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) {
- retval = i2c_master_send(i2c, buf, PAGE_SELECT_LEN);
- if (retval != PAGE_SELECT_LEN) {
- dev_err(&i2c->dev,
- "%s: I2C retry %d\n",
- __func__, retry + 1);
- msleep(20);
- } else {
- rmi4_data->current_page = page;
- break;
- }
- }
- } else
- return PAGE_SELECT_LEN;
- return (retval == PAGE_SELECT_LEN) ? retval : -EIO;
-}
-
- /**
- * synaptics_rmi4_i2c_read()
- *
- * Called by various functions in this driver, and also exported to
- * other expansion Function modules such as rmi_dev.
- *
- * This function reads data of an arbitrary length from the sensor,
- * starting from an assigned register address of the sensor, via I2C
- * with a retry mechanism.
- */
-static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data,
- unsigned short addr, unsigned char *data, unsigned short length)
-{
- int retval;
- unsigned char retry;
- unsigned char buf;
- struct i2c_msg msg[] = {
- {
- .addr = rmi4_data->i2c_client->addr,
- .flags = 0,
- .len = 1,
- .buf = &buf,
- },
- {
- .addr = rmi4_data->i2c_client->addr,
- .flags = I2C_M_RD,
- .len = length,
- .buf = data,
- },
- };
-
- buf = addr & MASK_8BIT;
-
- mutex_lock(&(rmi4_data->rmi4_io_ctrl_mutex));
-
- retval = synaptics_rmi4_set_page(rmi4_data, addr);
- if (retval != PAGE_SELECT_LEN)
- goto exit;
-
- for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) {
- if (i2c_transfer(rmi4_data->i2c_client->adapter, msg, 2) == 2) {
- retval = length;
- break;
- }
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: I2C retry %d\n",
- __func__, retry + 1);
- msleep(20);
- }
-
- if (retry == SYN_I2C_RETRY_TIMES) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: I2C read over retry limit\n",
- __func__);
- retval = -EIO;
- }
-
-exit:
- mutex_unlock(&(rmi4_data->rmi4_io_ctrl_mutex));
-
- return retval;
-}
-
- /**
- * synaptics_rmi4_i2c_write()
- *
- * Called by various functions in this driver, and also exported to
- * other expansion Function modules such as rmi_dev.
- *
- * This function writes data of an arbitrary length to the sensor,
- * starting from an assigned register address of the sensor, via I2C with
- * a retry mechanism.
- */
-static int synaptics_rmi4_i2c_write(struct synaptics_rmi4_data *rmi4_data,
- unsigned short addr, unsigned char *data, unsigned short length)
-{
- int retval;
- unsigned char retry;
- unsigned char buf[length + 1];
- struct i2c_msg msg[] = {
- {
- .addr = rmi4_data->i2c_client->addr,
- .flags = 0,
- .len = length + 1,
- .buf = buf,
- }
- };
-
- mutex_lock(&(rmi4_data->rmi4_io_ctrl_mutex));
-
- retval = synaptics_rmi4_set_page(rmi4_data, addr);
- if (retval != PAGE_SELECT_LEN)
- goto exit;
-
- buf[0] = addr & MASK_8BIT;
- memcpy(&buf[1], &data[0], length);
-
- for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) {
- if (i2c_transfer(rmi4_data->i2c_client->adapter, msg, 1) == 1) {
- retval = length;
- break;
- }
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: I2C retry %d\n",
- __func__, retry + 1);
- msleep(20);
- }
-
- if (retry == SYN_I2C_RETRY_TIMES) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: I2C write over retry limit\n",
- __func__);
- retval = -EIO;
- }
-
-exit:
- mutex_unlock(&(rmi4_data->rmi4_io_ctrl_mutex));
-
- return retval;
-}
-
- /**
- * synaptics_rmi4_f11_abs_report()
- *
- * Called by synaptics_rmi4_report_touch() when valid Function $11
- * finger data has been detected.
- *
- * This function reads the Function $11 data registers, determines the
- * status of each finger supported by the Function, processes any
- * necessary coordinate manipulation, reports the finger data to
- * the input subsystem, and returns the number of fingers detected.
- */
-static int synaptics_rmi4_f11_abs_report(struct synaptics_rmi4_data *rmi4_data,
- struct synaptics_rmi4_fn *fhandler)
-{
- int retval;
- unsigned char touch_count = 0; /* number of touch points */
- unsigned char reg_index;
- unsigned char finger;
- unsigned char fingers_supported;
- unsigned char num_of_finger_status_regs;
- unsigned char finger_shift;
- unsigned char finger_status;
- unsigned char data_reg_blk_size;
- unsigned char finger_status_reg[3];
- unsigned char data[F11_STD_DATA_LEN];
- unsigned short data_addr;
- unsigned short data_offset;
- int x;
- int y;
- int wx;
- int wy;
-
- /*
- * The number of finger status registers is determined by the
- * maximum number of fingers supported - 2 bits per finger. So
- * the number of finger status registers to read is:
- * register_count = ceil(max_num_of_fingers / 4)
- */
- fingers_supported = fhandler->num_of_data_points;
- num_of_finger_status_regs = (fingers_supported + 3) / 4;
- data_addr = fhandler->full_addr.data_base;
- data_reg_blk_size = fhandler->size_of_data_register_block;
-
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- data_addr,
- finger_status_reg,
- num_of_finger_status_regs);
- if (retval < 0)
- return 0;
-
- for (finger = 0; finger < fingers_supported; finger++) {
- reg_index = finger / 4;
- finger_shift = (finger % 4) * 2;
- finger_status = (finger_status_reg[reg_index] >> finger_shift)
- & MASK_2BIT;
-
- /*
- * Each 2-bit finger status field represents the following:
- * 00 = finger not present
- * 01 = finger present and data accurate
- * 10 = finger present but data may be inaccurate
- * 11 = reserved
- */
-#ifdef TYPE_B_PROTOCOL
- input_mt_slot(rmi4_data->input_dev, finger);
- input_mt_report_slot_state(rmi4_data->input_dev,
- MT_TOOL_FINGER, finger_status != 0);
-#endif
-
- if (finger_status) {
- data_offset = data_addr +
- num_of_finger_status_regs +
- (finger * data_reg_blk_size);
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- data_offset,
- data,
- data_reg_blk_size);
- if (retval < 0)
- return 0;
-
- x = (data[0] << 4) | (data[2] & MASK_4BIT);
- y = (data[1] << 4) | ((data[2] >> 4) & MASK_4BIT);
- wx = (data[3] & MASK_4BIT);
- wy = (data[3] >> 4) & MASK_4BIT;
-
- if (rmi4_data->board->x_flip)
- x = rmi4_data->sensor_max_x - x;
- if (rmi4_data->board->y_flip)
- y = rmi4_data->sensor_max_y - y;
-
- dev_dbg(&rmi4_data->i2c_client->dev,
- "%s: Finger %d:\n"
- "status = 0x%02x\n"
- "x = %d\n"
- "y = %d\n"
- "wx = %d\n"
- "wy = %d\n",
- __func__, finger,
- finger_status,
- x, y, wx, wy);
-
- input_report_key(rmi4_data->input_dev,
- BTN_TOUCH, 1);
- input_report_key(rmi4_data->input_dev,
- BTN_TOOL_FINGER, 1);
- input_report_abs(rmi4_data->input_dev,
- ABS_MT_POSITION_X, x);
- input_report_abs(rmi4_data->input_dev,
- ABS_MT_POSITION_Y, y);
-
-#ifdef REPORT_2D_W
- input_report_abs(rmi4_data->input_dev,
- ABS_MT_TOUCH_MAJOR, max(wx, wy));
- input_report_abs(rmi4_data->input_dev,
- ABS_MT_TOUCH_MINOR, min(wx, wy));
-#endif
-#ifndef TYPE_B_PROTOCOL
- input_mt_sync(rmi4_data->input_dev);
-#endif
- touch_count++;
- }
- }
-
-#ifndef TYPE_B_PROTOCOL
- if (!touch_count)
- input_mt_sync(rmi4_data->input_dev);
-#else
- /* sync after groups of events */
- #ifdef KERNEL_ABOVE_3_7
- input_mt_sync_frame(rmi4_data->input_dev);
- #endif
-#endif
-
- input_sync(rmi4_data->input_dev);
-
- return touch_count;
-}
-
-static void synaptics_rmi4_f1a_report(struct synaptics_rmi4_data *rmi4_data,
- struct synaptics_rmi4_fn *fhandler)
-{
- int retval;
- unsigned char button;
- unsigned char index;
- unsigned char shift;
- unsigned char status;
- unsigned char *data;
- unsigned short data_addr = fhandler->full_addr.data_base;
- struct synaptics_rmi4_f1a_handle *f1a = fhandler->data;
- static unsigned char do_once = 1;
- static bool current_status[MAX_NUMBER_OF_BUTTONS];
-#ifdef NO_0D_WHILE_2D
- static bool before_2d_status[MAX_NUMBER_OF_BUTTONS];
- static bool while_2d_status[MAX_NUMBER_OF_BUTTONS];
-#endif
-
- if (do_once) {
- memset(current_status, 0, sizeof(current_status));
-#ifdef NO_0D_WHILE_2D
- memset(before_2d_status, 0, sizeof(before_2d_status));
- memset(while_2d_status, 0, sizeof(while_2d_status));
-#endif
- do_once = 0;
- }
-
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- data_addr,
- f1a->button_data_buffer,
- f1a->button_bitmask_size);
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to read button data registers\n",
- __func__);
- return;
- }
-
- data = f1a->button_data_buffer;
-
- for (button = 0; button < f1a->valid_button_count; button++) {
- index = button / 8;
- shift = button % 8;
- status = ((data[index] >> shift) & MASK_1BIT);
-
- if (current_status[button] == status)
- continue;
- else
- current_status[button] = status;
-
- dev_dbg(&rmi4_data->i2c_client->dev,
- "%s: Button %d (code %d) ->%d\n",
- __func__, button,
- f1a->button_map[button],
- status);
-#ifdef NO_0D_WHILE_2D
- if (rmi4_data->fingers_on_2d == false) {
- if (status == 1) {
- before_2d_status[button] = 1;
- } else {
- if (while_2d_status[button] == 1) {
- while_2d_status[button] = 0;
- continue;
- } else {
- before_2d_status[button] = 0;
- }
- }
- input_report_key(rmi4_data->input_dev,
- f1a->button_map[button],
- status);
- } else {
- if (before_2d_status[button] == 1) {
- before_2d_status[button] = 0;
- input_report_key(rmi4_data->input_dev,
- f1a->button_map[button],
- status);
- } else {
- if (status == 1)
- while_2d_status[button] = 1;
- else
- while_2d_status[button] = 0;
- }
- }
-#else
- input_report_key(rmi4_data->input_dev,
- f1a->button_map[button],
- status);
-#endif
- }
-
- input_sync(rmi4_data->input_dev);
-
- return;
-}
-
- /**
- * synaptics_rmi4_report_touch()
- *
- * Called by synaptics_rmi4_sensor_report().
- *
- * This function calls the appropriate finger data reporting function
- * based on the function handler it receives and returns the number of
- * fingers detected.
- */
-static void synaptics_rmi4_report_touch(struct synaptics_rmi4_data *rmi4_data,
- struct synaptics_rmi4_fn *fhandler,
- unsigned char *touch_count)
-{
- unsigned char touch_count_2d;
-
- dev_dbg(&rmi4_data->i2c_client->dev,
- "%s: Function %02x reporting\n",
- __func__, fhandler->fn_number);
-
- switch (fhandler->fn_number) {
- case SYNAPTICS_RMI4_F11:
- touch_count_2d = synaptics_rmi4_f11_abs_report(rmi4_data,
- fhandler);
-
- *touch_count += touch_count_2d;
-
- if (touch_count_2d)
- rmi4_data->fingers_on_2d = true;
- else
- rmi4_data->fingers_on_2d = false;
- break;
-
- case SYNAPTICS_RMI4_F1A:
- synaptics_rmi4_f1a_report(rmi4_data, fhandler);
- break;
-
- default:
- break;
- }
-
- return;
-}
-
- /**
- * synaptics_rmi4_sensor_report()
- *
- * Called by synaptics_rmi4_irq().
- *
- * This function determines the interrupt source(s) from the sensor
- * and calls synaptics_rmi4_report_touch() with the appropriate
- * function handler for each function with valid data inputs.
- */
-static int synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *rmi4_data)
-{
- int retval;
- unsigned char touch_count = 0;
- unsigned char intr[MAX_INTR_REGISTERS];
- struct synaptics_rmi4_fn *fhandler;
- struct synaptics_rmi4_exp_fn *exp_fhandler;
- struct synaptics_rmi4_device_info *rmi;
-
- rmi = &(rmi4_data->rmi4_mod_info);
-
- /*
- * Get interrupt status information from F01 Data1 register to
- * determine the source(s) that are flagging the interrupt.
- */
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- rmi4_data->f01_data_base_addr + 1,
- intr,
- rmi4_data->num_of_intr_regs);
- if (retval < 0)
- return retval;
-
- /*
- * Traverse the function handler list and service the source(s)
- * of the interrupt accordingly.
- */
- if (!list_empty(&rmi->support_fn_list)) {
- list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
- if (fhandler->num_of_data_sources) {
- if (fhandler->intr_mask &
- intr[fhandler->intr_reg_num]) {
- synaptics_rmi4_report_touch(rmi4_data,
- fhandler, &touch_count);
- }
- }
- }
- }
-
- mutex_lock(&exp_fn_list_mutex);
- if (!list_empty(&exp_fn_list)) {
- list_for_each_entry(exp_fhandler, &exp_fn_list, link) {
- if (exp_fhandler->inserted &&
- (exp_fhandler->func_attn != NULL))
- exp_fhandler->func_attn(rmi4_data, intr[0]);
- }
- }
- mutex_unlock(&exp_fn_list_mutex);
-
- return touch_count;
-}
-
- /**
- * synaptics_rmi4_irq()
- *
- * Called by the kernel when an interrupt occurs (when the sensor
- * asserts the attention irq).
- *
- * This function is the ISR thread and handles the acquisition
- * and the reporting of finger data when the presence of fingers
- * is detected.
- */
-static irqreturn_t synaptics_rmi4_irq(int irq, void *data)
-{
- struct synaptics_rmi4_data *rmi4_data = data;
-
- synaptics_rmi4_sensor_report(rmi4_data);
-
- return IRQ_HANDLED;
-}
-
- /**
- * synaptics_rmi4_irq_enable()
- *
- * Called by synaptics_rmi4_probe() and the power management functions
- * in this driver and also exported to other expansion Function modules
- * such as rmi_dev.
- *
- * This function handles the enabling and disabling of the attention
- * irq including the setting up of the ISR thread.
- */
-static int synaptics_rmi4_irq_enable(struct synaptics_rmi4_data *rmi4_data,
- bool enable)
-{
- int retval = 0;
- unsigned char intr_status;
- const struct synaptics_rmi4_platform_data *platform_data =
- rmi4_data->i2c_client->dev.platform_data;
-
- if (enable) {
- if (rmi4_data->irq_enabled)
- return retval;
-
- /* Clear interrupts first */
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- rmi4_data->f01_data_base_addr + 1,
- &intr_status,
- rmi4_data->num_of_intr_regs);
- if (retval < 0)
- return retval;
-
- retval = request_threaded_irq(rmi4_data->irq, NULL,
- synaptics_rmi4_irq, platform_data->irq_flags,
- DRIVER_NAME, rmi4_data);
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to create irq thread\n",
- __func__);
- return retval;
- }
-
- rmi4_data->irq_enabled = true;
- } else {
- if (rmi4_data->irq_enabled) {
- disable_irq(rmi4_data->irq);
- free_irq(rmi4_data->irq, rmi4_data);
- rmi4_data->irq_enabled = false;
- }
- }
-
- return retval;
-}
-
- /**
- * synaptics_rmi4_f11_init()
- *
- * Called by synaptics_rmi4_query_device().
- *
- * This funtion parses information from the Function 11 registers
- * and determines the number of fingers supported, x and y data ranges,
- * offset to the associated interrupt status register, interrupt bit
- * mask, and gathers finger data acquisition capabilities from the query
- * registers.
- */
-static int synaptics_rmi4_f11_init(struct synaptics_rmi4_data *rmi4_data,
- struct synaptics_rmi4_fn *fhandler,
- struct synaptics_rmi4_fn_desc *fd,
- unsigned int intr_count)
-{
- int retval;
- unsigned char ii;
- unsigned char intr_offset;
- unsigned char abs_data_size;
- unsigned char abs_data_blk_size;
- unsigned char query[F11_STD_QUERY_LEN];
- unsigned char control[F11_STD_CTRL_LEN];
-
- fhandler->fn_number = fd->fn_number;
- fhandler->num_of_data_sources = fd->intr_src_count;
-
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- fhandler->full_addr.query_base,
- query,
- sizeof(query));
- if (retval < 0)
- return retval;
-
- /* Maximum number of fingers supported */
- if ((query[1] & MASK_3BIT) <= 4)
- fhandler->num_of_data_points = (query[1] & MASK_3BIT) + 1;
- else if ((query[1] & MASK_3BIT) == 5)
- fhandler->num_of_data_points = 10;
-
- rmi4_data->num_of_fingers = fhandler->num_of_data_points;
-
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- fhandler->full_addr.ctrl_base,
- control,
- sizeof(control));
- if (retval < 0)
- return retval;
-
- /* Maximum x and y */
- rmi4_data->sensor_max_x = ((control[6] & MASK_8BIT) << 0) |
- ((control[7] & MASK_4BIT) << 8);
- rmi4_data->sensor_max_y = ((control[8] & MASK_8BIT) << 0) |
- ((control[9] & MASK_4BIT) << 8);
- dev_dbg(&rmi4_data->i2c_client->dev,
- "%s: Function %02x max x = %d max y = %d\n",
- __func__, fhandler->fn_number,
- rmi4_data->sensor_max_x,
- rmi4_data->sensor_max_y);
-
- fhandler->intr_reg_num = (intr_count + 7) / 8;
- if (fhandler->intr_reg_num != 0)
- fhandler->intr_reg_num -= 1;
-
- /* Set an enable bit for each data source */
- intr_offset = intr_count % 8;
- fhandler->intr_mask = 0;
- for (ii = intr_offset;
- ii < ((fd->intr_src_count & MASK_3BIT) +
- intr_offset);
- ii++)
- fhandler->intr_mask |= 1 << ii;
-
- abs_data_size = query[5] & MASK_2BIT;
- abs_data_blk_size = 3 + (2 * (abs_data_size == 0 ? 1 : 0));
- fhandler->size_of_data_register_block = abs_data_blk_size;
-
- return retval;
-}
-
-static int synaptics_rmi4_f1a_alloc_mem(struct synaptics_rmi4_data *rmi4_data,
- struct synaptics_rmi4_fn *fhandler)
-{
- int retval;
- struct synaptics_rmi4_f1a_handle *f1a;
-
- f1a = kzalloc(sizeof(*f1a), GFP_KERNEL);
- if (!f1a) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to alloc mem for function handle\n",
- __func__);
- return -ENOMEM;
- }
-
- fhandler->data = (void *)f1a;
-
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- fhandler->full_addr.query_base,
- f1a->button_query.data,
- sizeof(f1a->button_query.data));
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to read query registers\n",
- __func__);
- return retval;
- }
-
- f1a->button_count = f1a->button_query.max_button_count + 1;
- f1a->button_bitmask_size = (f1a->button_count + 7) / 8;
-
- f1a->button_data_buffer = kcalloc(f1a->button_bitmask_size,
- sizeof(*(f1a->button_data_buffer)), GFP_KERNEL);
- if (!f1a->button_data_buffer) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to alloc mem for data buffer\n",
- __func__);
- return -ENOMEM;
- }
-
- f1a->button_map = kcalloc(f1a->button_count,
- sizeof(*(f1a->button_map)), GFP_KERNEL);
- if (!f1a->button_map) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to alloc mem for button map\n",
- __func__);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static int synaptics_rmi4_capacitance_button_map(
- struct synaptics_rmi4_data *rmi4_data,
- struct synaptics_rmi4_fn *fhandler)
-{
- unsigned char ii;
- struct synaptics_rmi4_f1a_handle *f1a = fhandler->data;
- const struct synaptics_rmi4_platform_data *pdata = rmi4_data->board;
-
- if (!pdata->capacitance_button_map) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: capacitance_button_map is" \
- "NULL in board file\n",
- __func__);
- return -ENODEV;
- } else if (!pdata->capacitance_button_map->map) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Button map is missing in board file\n",
- __func__);
- return -ENODEV;
- } else {
- if (pdata->capacitance_button_map->nbuttons !=
- f1a->button_count) {
- f1a->valid_button_count = min(f1a->button_count,
- pdata->capacitance_button_map->nbuttons);
- } else {
- f1a->valid_button_count = f1a->button_count;
- }
-
- for (ii = 0; ii < f1a->valid_button_count; ii++)
- f1a->button_map[ii] =
- pdata->capacitance_button_map->map[ii];
- }
-
- return 0;
-}
-
-static void synaptics_rmi4_f1a_kfree(struct synaptics_rmi4_fn *fhandler)
-{
- struct synaptics_rmi4_f1a_handle *f1a = fhandler->data;
-
- if (f1a) {
- kfree(f1a->button_data_buffer);
- kfree(f1a->button_map);
- kfree(f1a);
- fhandler->data = NULL;
- }
-
- return;
-}
-
-static int synaptics_rmi4_f1a_init(struct synaptics_rmi4_data *rmi4_data,
- struct synaptics_rmi4_fn *fhandler,
- struct synaptics_rmi4_fn_desc *fd,
- unsigned int intr_count)
-{
- int retval;
- unsigned char ii;
- unsigned short intr_offset;
-
- fhandler->fn_number = fd->fn_number;
- fhandler->num_of_data_sources = fd->intr_src_count;
-
- fhandler->intr_reg_num = (intr_count + 7) / 8;
- if (fhandler->intr_reg_num != 0)
- fhandler->intr_reg_num -= 1;
-
- /* Set an enable bit for each data source */
- intr_offset = intr_count % 8;
- fhandler->intr_mask = 0;
- for (ii = intr_offset;
- ii < ((fd->intr_src_count & MASK_3BIT) +
- intr_offset);
- ii++)
- fhandler->intr_mask |= 1 << ii;
-
- retval = synaptics_rmi4_f1a_alloc_mem(rmi4_data, fhandler);
- if (retval < 0)
- goto error_exit;
-
- retval = synaptics_rmi4_capacitance_button_map(rmi4_data, fhandler);
- if (retval < 0)
- goto error_exit;
-
- rmi4_data->button_0d_enabled = 1;
-
- return 0;
-
-error_exit:
- synaptics_rmi4_f1a_kfree(fhandler);
-
- return retval;
-}
-
-static int synaptics_rmi4_alloc_fh(struct synaptics_rmi4_fn **fhandler,
- struct synaptics_rmi4_fn_desc *rmi_fd, int page_number)
-{
- *fhandler = kmalloc(sizeof(**fhandler), GFP_KERNEL);
- if (!(*fhandler))
- return -ENOMEM;
-
- (*fhandler)->full_addr.data_base =
- (rmi_fd->data_base_addr |
- (page_number << 8));
- (*fhandler)->full_addr.ctrl_base =
- (rmi_fd->ctrl_base_addr |
- (page_number << 8));
- (*fhandler)->full_addr.cmd_base =
- (rmi_fd->cmd_base_addr |
- (page_number << 8));
- (*fhandler)->full_addr.query_base =
- (rmi_fd->query_base_addr |
- (page_number << 8));
-
- return 0;
-}
-
-
- /**
- * synaptics_rmi4_query_device_info()
- *
- * Called by synaptics_rmi4_query_device().
- *
- */
-static int synaptics_rmi4_query_device_info(
- struct synaptics_rmi4_data *rmi4_data)
-{
- int retval;
- unsigned char f01_query[F01_STD_QUERY_LEN];
- struct synaptics_rmi4_device_info *rmi = &(rmi4_data->rmi4_mod_info);
-
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- rmi4_data->f01_query_base_addr,
- f01_query,
- sizeof(f01_query));
- if (retval < 0)
- return retval;
-
- /* RMI Version 4.0 currently supported */
- rmi->version_major = 4;
- rmi->version_minor = 0;
-
- rmi->manufacturer_id = f01_query[0];
- rmi->product_props = f01_query[1];
- rmi->product_info[0] = f01_query[2] & MASK_7BIT;
- rmi->product_info[1] = f01_query[3] & MASK_7BIT;
- rmi->date_code[0] = f01_query[4] & MASK_5BIT;
- rmi->date_code[1] = f01_query[5] & MASK_4BIT;
- rmi->date_code[2] = f01_query[6] & MASK_5BIT;
- rmi->tester_id = ((f01_query[7] & MASK_7BIT) << 8) |
- (f01_query[8] & MASK_7BIT);
- rmi->serial_number = ((f01_query[9] & MASK_7BIT) << 8) |
- (f01_query[10] & MASK_7BIT);
- memcpy(rmi->product_id_string, &f01_query[11], 10);
-
- if (rmi->manufacturer_id != 1) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Non-Synaptics device found, manufacturer ID = %d\n",
- __func__, rmi->manufacturer_id);
- }
-
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- rmi4_data->f01_query_base_addr + F01_BUID_ID_OFFSET,
- rmi->build_id,
- sizeof(rmi->build_id));
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to read firmware build id (code %d)\n",
- __func__, retval);
- return retval;
- }
- return retval;
-}
-
- /**
- * synaptics_rmi4_query_device()
- *
- * Called by synaptics_rmi4_probe().
- *
- * This funtion scans the page description table, records the offsets
- * to the register types of Function $01, sets up the function handlers
- * for Function $11 and Function $12, determines the number of interrupt
- * sources from the sensor, adds valid Functions with data inputs to the
- * Function linked list, parses information from the query registers of
- * Function $01, and enables the interrupt sources from the valid Functions
- * with data inputs.
- */
-static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)
-{
- int retval;
- unsigned char ii;
- unsigned char page_number;
- unsigned char intr_count = 0;
- unsigned char data_sources = 0;
- unsigned short pdt_entry_addr;
- unsigned short intr_addr;
- struct synaptics_rmi4_f01_device_status status;
- struct synaptics_rmi4_fn_desc rmi_fd;
- struct synaptics_rmi4_fn *fhandler;
- struct synaptics_rmi4_device_info *rmi;
-
- rmi = &(rmi4_data->rmi4_mod_info);
-
- INIT_LIST_HEAD(&rmi->support_fn_list);
-
- /* Scan the page description tables of the pages to service */
- for (page_number = 0; page_number < PAGES_TO_SERVICE; page_number++) {
- for (pdt_entry_addr = PDT_START; pdt_entry_addr > PDT_END;
- pdt_entry_addr -= PDT_ENTRY_SIZE) {
- pdt_entry_addr |= (page_number << 8);
-
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- pdt_entry_addr,
- (unsigned char *)&rmi_fd,
- sizeof(rmi_fd));
- if (retval < 0)
- return retval;
-
- fhandler = NULL;
-
- if (rmi_fd.fn_number == 0) {
- dev_dbg(&rmi4_data->i2c_client->dev,
- "%s: Reached end of PDT\n",
- __func__);
- break;
- }
-
- dev_dbg(&rmi4_data->i2c_client->dev,
- "%s: F%02x found (page %d)\n",
- __func__, rmi_fd.fn_number,
- page_number);
-
- switch (rmi_fd.fn_number) {
- case SYNAPTICS_RMI4_F01:
- rmi4_data->f01_query_base_addr =
- rmi_fd.query_base_addr;
- rmi4_data->f01_ctrl_base_addr =
- rmi_fd.ctrl_base_addr;
- rmi4_data->f01_data_base_addr =
- rmi_fd.data_base_addr;
- rmi4_data->f01_cmd_base_addr =
- rmi_fd.cmd_base_addr;
-
- retval =
- synaptics_rmi4_query_device_info(rmi4_data);
- if (retval < 0)
- return retval;
-
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- rmi4_data->f01_data_base_addr,
- status.data,
- sizeof(status.data));
- if (retval < 0)
- return retval;
-
- if (status.flash_prog == 1) {
- pr_notice("%s: In flash prog mode, status = 0x%02x\n",
- __func__,
- status.status_code);
- goto flash_prog_mode;
- }
- break;
-
- case SYNAPTICS_RMI4_F34:
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- rmi_fd.ctrl_base_addr,
- rmi->config_id,
- sizeof(rmi->config_id));
- if (retval < 0)
- return retval;
- break;
-
- case SYNAPTICS_RMI4_F11:
- if (rmi_fd.intr_src_count == 0)
- break;
-
- retval = synaptics_rmi4_alloc_fh(&fhandler,
- &rmi_fd, page_number);
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to alloc for F%d\n",
- __func__,
- rmi_fd.fn_number);
- return retval;
- }
-
- retval = synaptics_rmi4_f11_init(rmi4_data,
- fhandler, &rmi_fd, intr_count);
- if (retval < 0)
- return retval;
- break;
-
- case SYNAPTICS_RMI4_F1A:
- if (rmi_fd.intr_src_count == 0)
- break;
-
- retval = synaptics_rmi4_alloc_fh(&fhandler,
- &rmi_fd, page_number);
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to alloc for F%d\n",
- __func__,
- rmi_fd.fn_number);
- return retval;
- }
-
- retval = synaptics_rmi4_f1a_init(rmi4_data,
- fhandler, &rmi_fd, intr_count);
- if (retval < 0)
- return retval;
- break;
- }
-
- /* Accumulate the interrupt count */
- intr_count += (rmi_fd.intr_src_count & MASK_3BIT);
-
- if (fhandler && rmi_fd.intr_src_count) {
- list_add_tail(&fhandler->link,
- &rmi->support_fn_list);
- }
- }
- }
-
-flash_prog_mode:
- rmi4_data->num_of_intr_regs = (intr_count + 7) / 8;
- dev_dbg(&rmi4_data->i2c_client->dev,
- "%s: Number of interrupt registers = %d\n",
- __func__, rmi4_data->num_of_intr_regs);
-
- memset(rmi4_data->intr_mask, 0x00, sizeof(rmi4_data->intr_mask));
-
- /*
- * Map out the interrupt bit masks for the interrupt sources
- * from the registered function handlers.
- */
- if (!list_empty(&rmi->support_fn_list)) {
- list_for_each_entry(fhandler, &rmi->support_fn_list, link)
- data_sources += fhandler->num_of_data_sources;
- }
- if (data_sources) {
- if (!list_empty(&rmi->support_fn_list)) {
- list_for_each_entry(fhandler,
- &rmi->support_fn_list, link) {
- if (fhandler->num_of_data_sources) {
- rmi4_data->intr_mask[fhandler->intr_reg_num] |=
- fhandler->intr_mask;
- }
- }
- }
- }
-
- /* Enable the interrupt sources */
- for (ii = 0; ii < rmi4_data->num_of_intr_regs; ii++) {
- if (rmi4_data->intr_mask[ii] != 0x00) {
- dev_dbg(&rmi4_data->i2c_client->dev,
- "%s: Interrupt enable mask %d = 0x%02x\n",
- __func__, ii, rmi4_data->intr_mask[ii]);
- intr_addr = rmi4_data->f01_ctrl_base_addr + 1 + ii;
- retval = synaptics_rmi4_i2c_write(rmi4_data,
- intr_addr,
- &(rmi4_data->intr_mask[ii]),
- sizeof(rmi4_data->intr_mask[ii]));
- if (retval < 0)
- return retval;
- }
- }
-
- return 0;
-}
-
-static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data)
-{
- int retval;
- unsigned char command = 0x01;
- struct synaptics_rmi4_fn *fhandler;
- struct synaptics_rmi4_device_info *rmi;
-
- rmi = &(rmi4_data->rmi4_mod_info);
-
- retval = synaptics_rmi4_i2c_write(rmi4_data,
- rmi4_data->f01_cmd_base_addr,
- &command,
- sizeof(command));
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to issue reset command, error = %d\n",
- __func__, retval);
- return retval;
- }
-
- msleep(100);
-
- if (!list_empty(&rmi->support_fn_list)) {
- list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
- if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
- synaptics_rmi4_f1a_kfree(fhandler);
- else
- kfree(fhandler->data);
- kfree(fhandler);
- }
- }
-
- retval = synaptics_rmi4_query_device(rmi4_data);
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to query device\n",
- __func__);
- return retval;
- }
-
- return 0;
-}
-
-/**
-* synaptics_rmi4_detection_work()
-*
-* Called by the kernel at the scheduled time.
-*
-* This function is a self-rearming work thread that checks for the
-* insertion and removal of other expansion Function modules such as
-* rmi_dev and calls their initialization and removal callback functions
-* accordingly.
-*/
-static void synaptics_rmi4_detection_work(struct work_struct *work)
-{
- struct synaptics_rmi4_exp_fn *exp_fhandler, *next_list_entry;
- struct synaptics_rmi4_data *rmi4_data =
- container_of(work, struct synaptics_rmi4_data,
- det_work.work);
-
- queue_delayed_work(rmi4_data->det_workqueue,
- &rmi4_data->det_work,
- msecs_to_jiffies(EXP_FN_DET_INTERVAL));
-
- mutex_lock(&exp_fn_list_mutex);
- if (!list_empty(&exp_fn_list)) {
- list_for_each_entry_safe(exp_fhandler,
- next_list_entry,
- &exp_fn_list,
- link) {
- if ((exp_fhandler->func_init != NULL) &&
- (exp_fhandler->inserted == false)) {
- exp_fhandler->func_init(rmi4_data);
- exp_fhandler->inserted = true;
- } else if ((exp_fhandler->func_init == NULL) &&
- (exp_fhandler->inserted == true)) {
- exp_fhandler->func_remove(rmi4_data);
- list_del(&exp_fhandler->link);
- kfree(exp_fhandler);
- }
- }
- }
- mutex_unlock(&exp_fn_list_mutex);
-
- return;
-}
-
-/**
-* synaptics_rmi4_new_function()
-*
-* Called by other expansion Function modules in their module init and
-* module exit functions.
-*
-* This function is used by other expansion Function modules such as
-* rmi_dev to register themselves with the driver by providing their
-* initialization and removal callback function pointers so that they
-* can be inserted or removed dynamically at module init and exit times,
-* respectively.
-*/
-void synaptics_rmi4_new_function(enum exp_fn fn_type, bool insert,
- int (*func_init)(struct synaptics_rmi4_data *rmi4_data),
- void (*func_remove)(struct synaptics_rmi4_data *rmi4_data),
- void (*func_attn)(struct synaptics_rmi4_data *rmi4_data,
- unsigned char intr_mask))
-{
- struct synaptics_rmi4_exp_fn *exp_fhandler;
-
- if (!exp_fn_inited) {
- mutex_init(&exp_fn_list_mutex);
- INIT_LIST_HEAD(&exp_fn_list);
- exp_fn_inited = 1;
- }
-
- mutex_lock(&exp_fn_list_mutex);
- if (insert) {
- exp_fhandler = kzalloc(sizeof(*exp_fhandler), GFP_KERNEL);
- if (!exp_fhandler) {
- pr_err("%s: Failed to alloc mem for expansion function\n",
- __func__);
- goto exit;
- }
- exp_fhandler->fn_type = fn_type;
- exp_fhandler->func_init = func_init;
- exp_fhandler->func_attn = func_attn;
- exp_fhandler->func_remove = func_remove;
- exp_fhandler->inserted = false;
- list_add_tail(&exp_fhandler->link, &exp_fn_list);
- } else {
- if (!list_empty(&exp_fn_list)) {
- list_for_each_entry(exp_fhandler, &exp_fn_list, link) {
- if (exp_fhandler->func_init == func_init) {
- exp_fhandler->inserted = false;
- exp_fhandler->func_init = NULL;
- exp_fhandler->func_attn = NULL;
- goto exit;
- }
- }
- }
- }
-
-exit:
- mutex_unlock(&exp_fn_list_mutex);
-
- return;
-}
-EXPORT_SYMBOL(synaptics_rmi4_new_function);
-
- /**
- * synaptics_rmi4_probe()
- *
- * Called by the kernel when an association with an I2C device of the
- * same name is made (after doing i2c_add_driver).
- *
- * This funtion allocates and initializes the resources for the driver
- * as an input driver, turns on the power to the sensor, queries the
- * sensor for its supported Functions and characteristics, registers
- * the driver to the input subsystem, sets up the interrupt, handles
- * the registration of the early_suspend and late_resume functions,
- * and creates a work queue for detection of other expansion Function
- * modules.
- */
-static int __devinit synaptics_rmi4_probe(struct i2c_client *client,
- const struct i2c_device_id *dev_id)
-{
- int retval;
- unsigned char ii;
- unsigned char attr_count;
- struct synaptics_rmi4_f1a_handle *f1a;
- struct synaptics_rmi4_fn *fhandler;
- struct synaptics_rmi4_data *rmi4_data;
- struct synaptics_rmi4_device_info *rmi;
- const struct synaptics_rmi4_platform_data *platform_data =
- client->dev.platform_data;
-
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_err(&client->dev,
- "%s: SMBus byte data not supported\n",
- __func__);
- return -EIO;
- }
-
- if (!platform_data) {
- dev_err(&client->dev,
- "%s: No platform data found\n",
- __func__);
- return -EINVAL;
- }
-
- rmi4_data = kzalloc(sizeof(*rmi4_data) * 2, GFP_KERNEL);
- if (!rmi4_data) {
- dev_err(&client->dev,
- "%s: Failed to alloc mem for rmi4_data\n",
- __func__);
- return -ENOMEM;
- }
-
- rmi = &(rmi4_data->rmi4_mod_info);
-
- rmi4_data->input_dev = input_allocate_device();
- if (rmi4_data->input_dev == NULL) {
- dev_err(&client->dev,
- "%s: Failed to allocate input device\n",
- __func__);
- retval = -ENOMEM;
- goto err_input_device;
- }
-
- if (platform_data->regulator_en) {
- rmi4_data->regulator = regulator_get(&client->dev, "vdd");
- if (IS_ERR(rmi4_data->regulator)) {
- dev_err(&client->dev,
- "%s: Failed to get regulator\n",
- __func__);
- retval = PTR_ERR(rmi4_data->regulator);
- goto err_regulator;
- }
- regulator_enable(rmi4_data->regulator);
- }
-
- rmi4_data->i2c_client = client;
- rmi4_data->current_page = MASK_8BIT;
- rmi4_data->board = platform_data;
- rmi4_data->touch_stopped = false;
- rmi4_data->sensor_sleep = false;
- rmi4_data->irq_enabled = false;
-
- rmi4_data->i2c_read = synaptics_rmi4_i2c_read;
- rmi4_data->i2c_write = synaptics_rmi4_i2c_write;
- rmi4_data->irq_enable = synaptics_rmi4_irq_enable;
- rmi4_data->reset_device = synaptics_rmi4_reset_device;
-
- init_waitqueue_head(&rmi4_data->wait);
- mutex_init(&(rmi4_data->rmi4_io_ctrl_mutex));
-
- retval = synaptics_rmi4_query_device(rmi4_data);
- if (retval < 0) {
- dev_err(&client->dev,
- "%s: Failed to query device\n",
- __func__);
- goto err_query_device;
- }
-
- i2c_set_clientdata(client, rmi4_data);
-
- rmi4_data->input_dev->name = DRIVER_NAME;
- rmi4_data->input_dev->phys = INPUT_PHYS_NAME;
- rmi4_data->input_dev->id.bustype = BUS_I2C;
- rmi4_data->input_dev->id.product = SYNAPTICS_RMI4_DRIVER_PRODUCT;
- rmi4_data->input_dev->id.version = SYNAPTICS_RMI4_DRIVER_VERSION;
- rmi4_data->input_dev->dev.parent = &client->dev;
- input_set_drvdata(rmi4_data->input_dev, rmi4_data);
-
- set_bit(EV_SYN, rmi4_data->input_dev->evbit);
- set_bit(EV_KEY, rmi4_data->input_dev->evbit);
- set_bit(EV_ABS, rmi4_data->input_dev->evbit);
- set_bit(BTN_TOUCH, rmi4_data->input_dev->keybit);
- set_bit(BTN_TOOL_FINGER, rmi4_data->input_dev->keybit);
-
-#ifdef INPUT_PROP_DIRECT
- set_bit(INPUT_PROP_DIRECT, rmi4_data->input_dev->propbit);
-#endif
-
- input_set_abs_params(rmi4_data->input_dev,
- ABS_MT_POSITION_X, 0,
- rmi4_data->sensor_max_x, 0, 0);
- input_set_abs_params(rmi4_data->input_dev,
- ABS_MT_POSITION_Y, 0,
- rmi4_data->sensor_max_y, 0, 0);
-#ifdef REPORT_2D_W
- input_set_abs_params(rmi4_data->input_dev,
- ABS_MT_TOUCH_MAJOR, 0,
- MAX_ABS_MT_TOUCH_MAJOR, 0, 0);
-#endif
-
-#ifdef TYPE_B_PROTOCOL
- input_mt_init_slots(rmi4_data->input_dev,
- rmi4_data->num_of_fingers);
-#endif
-
- f1a = NULL;
- if (!list_empty(&rmi->support_fn_list)) {
- list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
- if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
- f1a = fhandler->data;
- }
- }
-
- if (f1a) {
- for (ii = 0; ii < f1a->valid_button_count; ii++) {
- set_bit(f1a->button_map[ii],
- rmi4_data->input_dev->keybit);
- input_set_capability(rmi4_data->input_dev,
- EV_KEY, f1a->button_map[ii]);
- }
- }
-
- retval = input_register_device(rmi4_data->input_dev);
- if (retval) {
- dev_err(&client->dev,
- "%s: Failed to register input device\n",
- __func__);
- goto err_register_input;
- }
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
- rmi4_data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
- rmi4_data->early_suspend.suspend = synaptics_rmi4_early_suspend;
- rmi4_data->early_suspend.resume = synaptics_rmi4_late_resume;
- register_early_suspend(&rmi4_data->early_suspend);
-#endif
-
- if (!exp_fn_inited) {
- mutex_init(&exp_fn_list_mutex);
- INIT_LIST_HEAD(&exp_fn_list);
- exp_fn_inited = 1;
- }
-
- rmi4_data->det_workqueue =
- create_singlethread_workqueue("rmi_det_workqueue");
- INIT_DELAYED_WORK(&rmi4_data->det_work,
- synaptics_rmi4_detection_work);
- queue_delayed_work(rmi4_data->det_workqueue,
- &rmi4_data->det_work,
- msecs_to_jiffies(EXP_FN_DET_INTERVAL));
-
- if (platform_data->gpio_config) {
- retval = platform_data->gpio_config(platform_data->irq_gpio,
- true);
- if (retval < 0) {
- dev_err(&client->dev,
- "%s: Failed to configure GPIO\n",
- __func__);
- goto err_gpio;
- }
- }
-
- rmi4_data->irq = gpio_to_irq(platform_data->irq_gpio);
-
- retval = synaptics_rmi4_irq_enable(rmi4_data, true);
- if (retval < 0) {
- dev_err(&client->dev,
- "%s: Failed to enable attention interrupt\n",
- __func__);
- goto err_enable_irq;
- }
-
- for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
- retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj,
- &attrs[attr_count].attr);
- if (retval < 0) {
- dev_err(&client->dev,
- "%s: Failed to create sysfs attributes\n",
- __func__);
- goto err_sysfs;
- }
- }
-
- return retval;
-
-err_sysfs:
- for (attr_count--; attr_count >= 0; attr_count--) {
- sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
- &attrs[attr_count].attr);
- }
-
-err_enable_irq:
-err_gpio:
- input_unregister_device(rmi4_data->input_dev);
-
-err_register_input:
-err_query_device:
- if (platform_data->regulator_en) {
- regulator_disable(rmi4_data->regulator);
- regulator_put(rmi4_data->regulator);
- }
-
- if (!list_empty(&rmi->support_fn_list)) {
- list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
- if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
- synaptics_rmi4_f1a_kfree(fhandler);
- else
- kfree(fhandler->data);
- kfree(fhandler);
- }
- }
-
-err_regulator:
- input_free_device(rmi4_data->input_dev);
- rmi4_data->input_dev = NULL;
-
-err_input_device:
- kfree(rmi4_data);
-
- return retval;
-}
-
- /**
- * synaptics_rmi4_remove()
- *
- * Called by the kernel when the association with an I2C device of the
- * same name is broken (when the driver is unloaded).
- *
- * This funtion terminates the work queue, stops sensor data acquisition,
- * frees the interrupt, unregisters the driver from the input subsystem,
- * turns off the power to the sensor, and frees other allocated resources.
- */
-static int __devexit synaptics_rmi4_remove(struct i2c_client *client)
-{
- unsigned char attr_count;
- struct synaptics_rmi4_fn *fhandler;
- struct synaptics_rmi4_data *rmi4_data = i2c_get_clientdata(client);
- struct synaptics_rmi4_device_info *rmi;
- const struct synaptics_rmi4_platform_data *platform_data =
- rmi4_data->board;
-
- rmi = &(rmi4_data->rmi4_mod_info);
-
- cancel_delayed_work_sync(&rmi4_data->det_work);
- flush_workqueue(rmi4_data->det_workqueue);
- destroy_workqueue(rmi4_data->det_workqueue);
-
- rmi4_data->touch_stopped = true;
- wake_up(&rmi4_data->wait);
-
- synaptics_rmi4_irq_enable(rmi4_data, false);
-
- for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
- sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
- &attrs[attr_count].attr);
- }
-
- input_unregister_device(rmi4_data->input_dev);
-
- if (platform_data->regulator_en) {
- regulator_disable(rmi4_data->regulator);
- regulator_put(rmi4_data->regulator);
- }
-
- if (!list_empty(&rmi->support_fn_list)) {
- list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
- if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
- synaptics_rmi4_f1a_kfree(fhandler);
- else
- kfree(fhandler->data);
- kfree(fhandler);
- }
- }
- input_free_device(rmi4_data->input_dev);
-
- kfree(rmi4_data);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
- /**
- * synaptics_rmi4_sensor_sleep()
- *
- * Called by synaptics_rmi4_early_suspend() and synaptics_rmi4_suspend().
- *
- * This function stops finger data acquisition and puts the sensor to sleep.
- */
-static void synaptics_rmi4_sensor_sleep(struct synaptics_rmi4_data *rmi4_data)
-{
- int retval;
- unsigned char device_ctrl;
-
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- rmi4_data->f01_ctrl_base_addr,
- &device_ctrl,
- sizeof(device_ctrl));
- if (retval < 0) {
- dev_err(&(rmi4_data->input_dev->dev),
- "%s: Failed to enter sleep mode\n",
- __func__);
- rmi4_data->sensor_sleep = false;
- return;
- }
-
- device_ctrl = (device_ctrl & ~MASK_3BIT);
- device_ctrl = (device_ctrl | NO_SLEEP_OFF | SENSOR_SLEEP);
-
- retval = synaptics_rmi4_i2c_write(rmi4_data,
- rmi4_data->f01_ctrl_base_addr,
- &device_ctrl,
- sizeof(device_ctrl));
- if (retval < 0) {
- dev_err(&(rmi4_data->input_dev->dev),
- "%s: Failed to enter sleep mode\n",
- __func__);
- rmi4_data->sensor_sleep = false;
- return;
- } else {
- rmi4_data->sensor_sleep = true;
- }
-
- return;
-}
-
- /**
- * synaptics_rmi4_sensor_wake()
- *
- * Called by synaptics_rmi4_resume() and synaptics_rmi4_late_resume().
- *
- * This function wakes the sensor from sleep.
- */
-static void synaptics_rmi4_sensor_wake(struct synaptics_rmi4_data *rmi4_data)
-{
- int retval;
- unsigned char device_ctrl;
-
- retval = synaptics_rmi4_i2c_read(rmi4_data,
- rmi4_data->f01_ctrl_base_addr,
- &device_ctrl,
- sizeof(device_ctrl));
- if (retval < 0) {
- dev_err(&(rmi4_data->input_dev->dev),
- "%s: Failed to wake from sleep mode\n",
- __func__);
- rmi4_data->sensor_sleep = true;
- return;
- }
-
- device_ctrl = (device_ctrl & ~MASK_3BIT);
- device_ctrl = (device_ctrl | NO_SLEEP_OFF | NORMAL_OPERATION);
-
- retval = synaptics_rmi4_i2c_write(rmi4_data,
- rmi4_data->f01_ctrl_base_addr,
- &device_ctrl,
- sizeof(device_ctrl));
- if (retval < 0) {
- dev_err(&(rmi4_data->input_dev->dev),
- "%s: Failed to wake from sleep mode\n",
- __func__);
- rmi4_data->sensor_sleep = true;
- return;
- } else {
- rmi4_data->sensor_sleep = false;
- }
-
- return;
-}
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
- /**
- * synaptics_rmi4_early_suspend()
- *
- * Called by the kernel during the early suspend phase when the system
- * enters suspend.
- *
- * This function calls synaptics_rmi4_sensor_sleep() to stop finger
- * data acquisition and put the sensor to sleep.
- */
-static void synaptics_rmi4_early_suspend(struct early_suspend *h)
-{
- struct synaptics_rmi4_data *rmi4_data =
- container_of(h, struct synaptics_rmi4_data,
- early_suspend);
-
- rmi4_data->touch_stopped = true;
- wake_up(&rmi4_data->wait);
- synaptics_rmi4_irq_enable(rmi4_data, false);
- synaptics_rmi4_sensor_sleep(rmi4_data);
-
- if (rmi4_data->full_pm_cycle)
- synaptics_rmi4_suspend(&(rmi4_data->input_dev->dev));
-
- return;
-}
-
- /**
- * synaptics_rmi4_late_resume()
- *
- * Called by the kernel during the late resume phase when the system
- * wakes up from suspend.
- *
- * This function goes through the sensor wake process if the system wakes
- * up from early suspend (without going into suspend).
- */
-static void synaptics_rmi4_late_resume(struct early_suspend *h)
-{
- struct synaptics_rmi4_data *rmi4_data =
- container_of(h, struct synaptics_rmi4_data,
- early_suspend);
-
- if (rmi4_data->full_pm_cycle)
- synaptics_rmi4_resume(&(rmi4_data->input_dev->dev));
-
- if (rmi4_data->sensor_sleep == true) {
- synaptics_rmi4_sensor_wake(rmi4_data);
- rmi4_data->touch_stopped = false;
- synaptics_rmi4_irq_enable(rmi4_data, true);
- }
-
- return;
-}
-#endif
-
- /**
- * synaptics_rmi4_suspend()
- *
- * Called by the kernel during the suspend phase when the system
- * enters suspend.
- *
- * This function stops finger data acquisition and puts the sensor to
- * sleep (if not already done so during the early suspend phase),
- * disables the interrupt, and turns off the power to the sensor.
- */
-static int synaptics_rmi4_suspend(struct device *dev)
-{
- struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
- const struct synaptics_rmi4_platform_data *platform_data =
- rmi4_data->board;
-
- if (!rmi4_data->sensor_sleep) {
- rmi4_data->touch_stopped = true;
- wake_up(&rmi4_data->wait);
- synaptics_rmi4_irq_enable(rmi4_data, false);
- synaptics_rmi4_sensor_sleep(rmi4_data);
- }
-
- if (platform_data->regulator_en)
- regulator_disable(rmi4_data->regulator);
-
- return 0;
-}
-
- /**
- * synaptics_rmi4_resume()
- *
- * Called by the kernel during the resume phase when the system
- * wakes up from suspend.
- *
- * This function turns on the power to the sensor, wakes the sensor
- * from sleep, enables the interrupt, and starts finger data
- * acquisition.
- */
-static int synaptics_rmi4_resume(struct device *dev)
-{
- struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
- const struct synaptics_rmi4_platform_data *platform_data =
- rmi4_data->board;
-
- if (platform_data->regulator_en)
- regulator_enable(rmi4_data->regulator);
-
- synaptics_rmi4_sensor_wake(rmi4_data);
- rmi4_data->touch_stopped = false;
- synaptics_rmi4_irq_enable(rmi4_data, true);
-
- return 0;
-}
-
-static const struct dev_pm_ops synaptics_rmi4_dev_pm_ops = {
- .suspend = synaptics_rmi4_suspend,
- .resume = synaptics_rmi4_resume,
-};
-#endif
-
-static const struct i2c_device_id synaptics_rmi4_id_table[] = {
- {DRIVER_NAME, 0},
- {},
-};
-MODULE_DEVICE_TABLE(i2c, synaptics_rmi4_id_table);
-
-static struct i2c_driver synaptics_rmi4_driver = {
- .driver = {
- .name = DRIVER_NAME,
- .owner = THIS_MODULE,
-#ifdef CONFIG_PM
- .pm = &synaptics_rmi4_dev_pm_ops,
-#endif
- },
- .probe = synaptics_rmi4_probe,
- .remove = __devexit_p(synaptics_rmi4_remove),
- .id_table = synaptics_rmi4_id_table,
-};
-
- /**
- * synaptics_rmi4_init()
- *
- * Called by the kernel during do_initcalls (if built-in)
- * or when the driver is loaded (if a module).
- *
- * This function registers the driver to the I2C subsystem.
- *
- */
-static int __init synaptics_rmi4_init(void)
-{
- return i2c_add_driver(&synaptics_rmi4_driver);
-}
-
- /**
- * synaptics_rmi4_exit()
- *
- * Called by the kernel when the driver is unloaded.
- *
- * This funtion unregisters the driver from the I2C subsystem.
- *
- */
-static void __exit synaptics_rmi4_exit(void)
-{
- i2c_del_driver(&synaptics_rmi4_driver);
-}
-
-module_init(synaptics_rmi4_init);
-module_exit(synaptics_rmi4_exit);
-
-MODULE_AUTHOR("Synaptics, Inc.");
-MODULE_DESCRIPTION("Synaptics RMI4 I2C Touch Driver");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(SYNAPTICS_RMI4_DRIVER_VERSION);
diff --git a/kernel/drivers/input/touchscreen/synaptics_i2c_rmi4.h b/kernel/drivers/input/touchscreen/synaptics_i2c_rmi4.h
deleted file mode 100644
index ecb9b9415e8a..000000000000
--- a/kernel/drivers/input/touchscreen/synaptics_i2c_rmi4.h
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Synaptics RMI4 touchscreen driver
- *
- * Copyright (C) 2012 Synaptics Incorporated
- *
- * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
- * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef _SYNAPTICS_DSX_RMI4_H_
-#define _SYNAPTICS_DSX_RMI4_H_
-
-#define SYNAPTICS_RMI4_DS4 0x0001
-#define SYNAPTICS_RMI4_DS5 0x0002
-#define SYNAPTICS_RMI4_DRIVER_PRODUCT SYNAPTICS_RMI4_DS4
-#define SYNAPTICS_RMI4_DRIVER_VERSION 0x1001
-
-#include <linux/version.h>
-#ifdef CONFIG_HAS_EARLYSUSPEND
-#include <linux/earlysuspend.h>
-#endif
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38))
-#define KERNEL_ABOVE_2_6_38
-#endif
-
-#ifdef KERNEL_ABOVE_2_6_38
-#define sstrtoul(...) kstrtoul(__VA_ARGS__)
-#else
-#define sstrtoul(...) strict_strtoul(__VA_ARGS__)
-#endif
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 7, 0))
-#define KERNEL_ABOVE_3_7
-#endif
-
-#define PDT_PROPS (0x00EF)
-#define PDT_START (0x00E9)
-#define PDT_END (0x000A)
-#define PDT_ENTRY_SIZE (0x0006)
-#define PAGES_TO_SERVICE (10)
-#define PAGE_SELECT_LEN (2)
-
-#define SYNAPTICS_RMI4_F01 (0x01)
-#define SYNAPTICS_RMI4_F11 (0x11)
-#define SYNAPTICS_RMI4_F1A (0x1a)
-#define SYNAPTICS_RMI4_F34 (0x34)
-#define SYNAPTICS_RMI4_F54 (0x54)
-#define SYNAPTICS_RMI4_F55 (0x55)
-
-#define SYNAPTICS_RMI4_PRODUCT_INFO_SIZE 2
-#define SYNAPTICS_RMI4_DATE_CODE_SIZE 3
-#define SYNAPTICS_RMI4_PRODUCT_ID_SIZE 10
-#define SYNAPTICS_RMI4_BUILD_ID_SIZE 3
-
-#define MAX_NUMBER_OF_FINGERS 10
-#define MAX_NUMBER_OF_BUTTONS 4
-#define MAX_INTR_REGISTERS 4
-
-#define MASK_16BIT 0xFFFF
-#define MASK_8BIT 0xFF
-#define MASK_7BIT 0x7F
-#define MASK_6BIT 0x3F
-#define MASK_5BIT 0x1F
-#define MASK_4BIT 0x0F
-#define MASK_3BIT 0x07
-#define MASK_2BIT 0x03
-#define MASK_1BIT 0x01
-
-/*
- * struct synaptics_rmi4_fn_desc - function descriptor fields in PDT
- * @query_base_addr: base address for query registers
- * @cmd_base_addr: base address for command registers
- * @ctrl_base_addr: base address for control registers
- * @data_base_addr: base address for data registers
- * @intr_src_count: number of interrupt sources
- * @fn_number: function number
- */
-struct synaptics_rmi4_fn_desc {
- unsigned char query_base_addr;
- unsigned char cmd_base_addr;
- unsigned char ctrl_base_addr;
- unsigned char data_base_addr;
- unsigned char intr_src_count;
- unsigned char fn_number;
-};
-
-/*
- * synaptics_rmi4_fn_full_addr - full 16-bit base addresses
- * @query_base: 16-bit base address for query registers
- * @cmd_base: 16-bit base address for data registers
- * @ctrl_base: 16-bit base address for command registers
- * @data_base: 16-bit base address for control registers
- */
-struct synaptics_rmi4_fn_full_addr {
- unsigned short query_base;
- unsigned short cmd_base;
- unsigned short ctrl_base;
- unsigned short data_base;
-};
-
-/*
- * struct synaptics_rmi4_fn - function handler data structure
- * @fn_number: function number
- * @num_of_data_sources: number of data sources
- * @num_of_data_points: maximum number of fingers supported
- * @size_of_data_register_block: data register block size
- * @data1_offset: offset to data1 register from data base address
- * @intr_reg_num: index to associated interrupt register
- * @intr_mask: interrupt mask
- * @full_addr: full 16-bit base addresses of function registers
- * @link: linked list for function handlers
- * @data_size: size of private data
- * @data: pointer to private data
- */
-struct synaptics_rmi4_fn {
- unsigned char fn_number;
- unsigned char num_of_data_sources;
- unsigned char num_of_data_points;
- unsigned char size_of_data_register_block;
- unsigned char data1_offset;
- unsigned char intr_reg_num;
- unsigned char intr_mask;
- struct synaptics_rmi4_fn_full_addr full_addr;
- struct list_head link;
- int data_size;
- void *data;
-};
-
-/*
- * struct synaptics_rmi4_device_info - device information
- * @version_major: rmi protocol major version number
- * @version_minor: rmi protocol minor version number
- * @manufacturer_id: manufacturer id
- * @product_props: product properties information
- * @product_info: product info array
- * @date_code: device manufacture date
- * @tester_id: tester id array
- * @serial_number: device serial number
- * @product_id_string: device product id
- * @support_fn_list: linked list for function handlers
- */
-struct synaptics_rmi4_device_info {
- unsigned int version_major;
- unsigned int version_minor;
- unsigned char manufacturer_id;
- unsigned char product_props;
- unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE];
- unsigned char date_code[SYNAPTICS_RMI4_DATE_CODE_SIZE];
- unsigned short tester_id;
- unsigned short serial_number;
- unsigned char product_id_string[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
- unsigned char build_id[SYNAPTICS_RMI4_BUILD_ID_SIZE];
- unsigned char config_id[3];
- struct list_head support_fn_list;
-};
-
-/*
- * struct synaptics_rmi4_data - rmi4 device instance data
- * @i2c_client: pointer to associated i2c client
- * @input_dev: pointer to associated input device
- * @board: constant pointer to platform data
- * @rmi4_mod_info: device information
- * @regulator: pointer to associated regulator
- * @rmi4_io_ctrl_mutex: mutex for i2c i/o control
- * @det_work: work thread instance for expansion function detection
- * @det_workqueue: pointer to work queue for work thread instance
- * @early_suspend: instance to support early suspend power management
- * @current_page: current page in sensor to acess
- * @button_0d_enabled: flag for 0d button support
- * @full_pm_cycle: flag for full power management cycle in early suspend stage
- * @num_of_intr_regs: number of interrupt registers
- * @f01_query_base_addr: query base address for f01
- * @f01_cmd_base_addr: command base address for f01
- * @f01_ctrl_base_addr: control base address for f01
- * @f01_data_base_addr: data base address for f01
- * @irq: attention interrupt
- * @sensor_max_x: sensor maximum x value
- * @sensor_max_y: sensor maximum y value
- * @irq_enabled: flag for indicating interrupt enable status
- * @touch_stopped: flag to stop interrupt thread processing
- * @fingers_on_2d: flag to indicate presence of fingers in 2d area
- * @sensor_sleep: flag to indicate sleep state of sensor
- * @wait: wait queue for touch data polling in interrupt thread
- * @i2c_read: pointer to i2c read function
- * @i2c_write: pointer to i2c write function
- * @irq_enable: pointer to irq enable function
- */
-struct synaptics_rmi4_data {
- struct i2c_client *i2c_client;
- struct input_dev *input_dev;
- const struct synaptics_rmi4_platform_data *board;
- struct synaptics_rmi4_device_info rmi4_mod_info;
- struct regulator *regulator;
- struct mutex rmi4_io_ctrl_mutex;
- struct delayed_work det_work;
- struct workqueue_struct *det_workqueue;
- struct early_suspend early_suspend;
- unsigned char current_page;
- unsigned char button_0d_enabled;
- unsigned char full_pm_cycle;
- unsigned char num_of_rx;
- unsigned char num_of_tx;
- unsigned char num_of_fingers;
- unsigned char intr_mask[MAX_INTR_REGISTERS];
- unsigned short num_of_intr_regs;
- unsigned short f01_query_base_addr;
- unsigned short f01_cmd_base_addr;
- unsigned short f01_ctrl_base_addr;
- unsigned short f01_data_base_addr;
- int irq;
- int sensor_max_x;
- int sensor_max_y;
- bool irq_enabled;
- bool touch_stopped;
- bool fingers_on_2d;
- bool sensor_sleep;
- wait_queue_head_t wait;
- int (*i2c_read)(struct synaptics_rmi4_data *pdata, unsigned short addr,
- unsigned char *data, unsigned short length);
- int (*i2c_write)(struct synaptics_rmi4_data *pdata, unsigned short addr,
- unsigned char *data, unsigned short length);
- int (*irq_enable)(struct synaptics_rmi4_data *rmi4_data, bool enable);
- int (*reset_device)(struct synaptics_rmi4_data *rmi4_data);
-};
-
-enum exp_fn {
- RMI_DEV = 0,
- RMI_F34,
- RMI_F54,
- RMI_FW_UPDATER,
- RMI_LAST,
-};
-
-struct synaptics_rmi4_exp_fn_ptr {
- int (*read)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr,
- unsigned char *data, unsigned short length);
- int (*write)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr,
- unsigned char *data, unsigned short length);
- int (*enable)(struct synaptics_rmi4_data *rmi4_data, bool enable);
-};
-
-void synaptics_rmi4_new_function(enum exp_fn fn_type, bool insert,
- int (*func_init)(struct synaptics_rmi4_data *rmi4_data),
- void (*func_remove)(struct synaptics_rmi4_data *rmi4_data),
- void (*func_attn)(struct synaptics_rmi4_data *rmi4_data,
- unsigned char intr_mask));
-
-static inline ssize_t synaptics_rmi4_show_error(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- dev_warn(dev, "%s Attempted to read from write-only attribute %s\n",
- __func__, attr->attr.name);
- return -EPERM;
-}
-
-static inline ssize_t synaptics_rmi4_store_error(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- dev_warn(dev, "%s Attempted to write to read-only attribute %s\n",
- __func__, attr->attr.name);
- return -EPERM;
-}
-
-static inline void batohs(unsigned short *dest, unsigned char *src)
-{
- *dest = src[1] * 0x100 + src[0];
-}
-
-static inline void hstoba(unsigned char *dest, unsigned short src)
-{
- dest[0] = src % 0x100;
- dest[1] = src / 0x100;
-}
-
-#endif
diff --git a/kernel/drivers/input/touchscreen/synaptics_rmi_dev.c b/kernel/drivers/input/touchscreen/synaptics_rmi_dev.c
deleted file mode 100644
index 75857802c97a..000000000000
--- a/kernel/drivers/input/touchscreen/synaptics_rmi_dev.c
+++ /dev/null
@@ -1,710 +0,0 @@
-/*
- * Synaptics RMI4 touchscreen driver
- *
- * Copyright (C) 2012 Synaptics Incorporated
- *
- * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
- * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/input.h>
-#include <linux/gpio.h>
-#include <linux/uaccess.h>
-#include <linux/cdev.h>
-#include <linux/input/synaptics_dsx.h>
-#include "synaptics_i2c_rmi4.h"
-
-#define CHAR_DEVICE_NAME "rmi"
-#define DEVICE_CLASS_NAME "rmidev"
-#define DEV_NUMBER 1
-#define REG_ADDR_LIMIT 0xFFFF
-
-static ssize_t rmidev_sysfs_open_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t rmidev_sysfs_release_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t rmidev_sysfs_address_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t rmidev_sysfs_length_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-static ssize_t rmidev_sysfs_data_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-
-static ssize_t rmidev_sysfs_data_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count);
-
-struct rmidev_handle {
- dev_t dev_no;
- unsigned short address;
- unsigned int length;
- struct device dev;
- struct synaptics_rmi4_data *rmi4_data;
- struct synaptics_rmi4_exp_fn_ptr *fn_ptr;
- struct kobject *sysfs_dir;
- void *data;
-};
-
-struct rmidev_data {
- int ref_count;
- struct cdev main_dev;
- struct class *device_class;
- struct mutex file_mutex;
- struct rmidev_handle *rmi_dev;
-};
-
-static struct device_attribute attrs[] = {
- __ATTR(open, S_IWUGO,
- synaptics_rmi4_show_error,
- rmidev_sysfs_open_store),
- __ATTR(release, S_IWUGO,
- synaptics_rmi4_show_error,
- rmidev_sysfs_release_store),
- __ATTR(address, S_IWUGO,
- synaptics_rmi4_show_error,
- rmidev_sysfs_address_store),
- __ATTR(length, S_IWUGO,
- synaptics_rmi4_show_error,
- rmidev_sysfs_length_store),
- __ATTR(data, (S_IRUGO | S_IWUGO),
- rmidev_sysfs_data_show,
- rmidev_sysfs_data_store),
-};
-
-static int rmidev_major_num;
-
-static struct class *rmidev_device_class;
-
-static struct rmidev_handle *rmidev;
-
-static struct completion remove_complete;
-
-static ssize_t rmidev_sysfs_open_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- unsigned int input;
-
- if (sscanf(buf, "%u", &input) != 1)
- return -EINVAL;
-
- if (input != 1)
- return -EINVAL;
-
- rmidev->fn_ptr->enable(rmidev->rmi4_data, false);
- dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
- "%s: Attention interrupt disabled\n",
- __func__);
-
- return count;
-}
-
-static ssize_t rmidev_sysfs_release_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- unsigned int input;
-
- if (sscanf(buf, "%u", &input) != 1)
- return -EINVAL;
-
- if (input != 1)
- return -EINVAL;
-
- rmidev->fn_ptr->enable(rmidev->rmi4_data, true);
- dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
- "%s: Attention interrupt enabled\n",
- __func__);
-
- return count;
-}
-
-static ssize_t rmidev_sysfs_address_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- unsigned int input;
-
- if (sscanf(buf, "%u", &input) != 1)
- return -EINVAL;
-
- if (input > REG_ADDR_LIMIT)
- return -EINVAL;
-
- rmidev->address = (unsigned short)input;
-
- return count;
-}
-
-static ssize_t rmidev_sysfs_length_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- unsigned int input;
-
- if (sscanf(buf, "%u", &input) != 1)
- return -EINVAL;
-
- if (input > REG_ADDR_LIMIT)
- return -EINVAL;
-
- rmidev->length = input;
-
- return count;
-}
-
-static ssize_t rmidev_sysfs_data_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int retval;
- unsigned int data_length = rmidev->length;
-
- if (data_length > (REG_ADDR_LIMIT - rmidev->address))
- data_length = REG_ADDR_LIMIT - rmidev->address;
-
- if (data_length) {
- retval = rmidev->fn_ptr->read(rmidev->rmi4_data,
- rmidev->address,
- (unsigned char *)buf,
- data_length);
- if (retval < 0) {
- dev_err(&rmidev->rmi4_data->i2c_client->dev,
- "%s: Failed to read data\n",
- __func__);
- return retval;
- }
- } else {
- return -EINVAL;
- }
-
- return data_length;
-}
-
-static ssize_t rmidev_sysfs_data_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int retval;
- unsigned int data_length = rmidev->length;
-
- if (data_length > (REG_ADDR_LIMIT - rmidev->address))
- data_length = REG_ADDR_LIMIT - rmidev->address;
-
- if (data_length) {
- retval = rmidev->fn_ptr->write(rmidev->rmi4_data,
- rmidev->address,
- (unsigned char *)buf,
- data_length);
- if (retval < 0) {
- dev_err(&rmidev->rmi4_data->i2c_client->dev,
- "%s: Failed to write data\n",
- __func__);
- return retval;
- }
- } else {
- return -EINVAL;
- }
-
- return data_length;
-}
-
-/*
- * rmidev_llseek - used to set up register address
- *
- * @filp: file structure for seek
- * @off: offset
- * if whence == SEEK_SET,
- * high 16 bits: page address
- * low 16 bits: register address
- * if whence == SEEK_CUR,
- * offset from current position
- * if whence == SEEK_END,
- * offset from end position (0xFFFF)
- * @whence: SEEK_SET, SEEK_CUR, or SEEK_END
- */
-static loff_t rmidev_llseek(struct file *filp, loff_t off, int whence)
-{
- loff_t newpos;
- struct rmidev_data *dev_data = filp->private_data;
-
- if (IS_ERR(dev_data)) {
- pr_err("%s: Pointer of char device data is invalid", __func__);
- return -EBADF;
- }
-
- mutex_lock(&(dev_data->file_mutex));
-
- switch (whence) {
- case SEEK_SET:
- newpos = off;
- break;
- case SEEK_CUR:
- newpos = filp->f_pos + off;
- break;
- case SEEK_END:
- newpos = REG_ADDR_LIMIT + off;
- break;
- default:
- newpos = -EINVAL;
- goto clean_up;
- }
-
- if (newpos < 0 || newpos > REG_ADDR_LIMIT) {
- dev_err(&rmidev->rmi4_data->i2c_client->dev,
- "%s: New position 0x%04x is invalid\n",
- __func__, (unsigned int)newpos);
- newpos = -EINVAL;
- goto clean_up;
- }
-
- filp->f_pos = newpos;
-
-clean_up:
- mutex_unlock(&(dev_data->file_mutex));
-
- return newpos;
-}
-
-/*
- * rmidev_read: - use to read data from rmi device
- *
- * @filp: file structure for read
- * @buf: user space buffer pointer
- * @count: number of bytes to read
- * @f_pos: offset (starting register address)
- */
-static ssize_t rmidev_read(struct file *filp, char __user *buf,
- size_t count, loff_t *f_pos)
-{
- ssize_t retval;
- unsigned char tmpbuf[count + 1];
- struct rmidev_data *dev_data = filp->private_data;
-
- if (IS_ERR(dev_data)) {
- pr_err("%s: Pointer of char device data is invalid", __func__);
- return -EBADF;
- }
-
- if (count == 0)
- return 0;
-
- if (count > (REG_ADDR_LIMIT - *f_pos))
- count = REG_ADDR_LIMIT - *f_pos;
-
- mutex_lock(&(dev_data->file_mutex));
-
- retval = rmidev->fn_ptr->read(rmidev->rmi4_data,
- *f_pos,
- tmpbuf,
- count);
- if (retval < 0)
- goto clean_up;
-
- if (copy_to_user(buf, tmpbuf, count))
- retval = -EFAULT;
- else
- *f_pos += retval;
-
-clean_up:
- mutex_unlock(&(dev_data->file_mutex));
-
- return retval;
-}
-
-/*
- * rmidev_write: - used to write data to rmi device
- *
- * @filep: file structure for write
- * @buf: user space buffer pointer
- * @count: number of bytes to write
- * @f_pos: offset (starting register address)
- */
-static ssize_t rmidev_write(struct file *filp, const char __user *buf,
- size_t count, loff_t *f_pos)
-{
- ssize_t retval;
- unsigned char tmpbuf[count + 1];
- struct rmidev_data *dev_data = filp->private_data;
-
- if (IS_ERR(dev_data)) {
- pr_err("%s: Pointer of char device data is invalid", __func__);
- return -EBADF;
- }
-
- if (count == 0)
- return 0;
-
- if (count > (REG_ADDR_LIMIT - *f_pos))
- count = REG_ADDR_LIMIT - *f_pos;
-
- if (copy_from_user(tmpbuf, buf, count))
- return -EFAULT;
-
- mutex_lock(&(dev_data->file_mutex));
-
- retval = rmidev->fn_ptr->write(rmidev->rmi4_data,
- *f_pos,
- tmpbuf,
- count);
- if (retval >= 0)
- *f_pos += retval;
-
- mutex_unlock(&(dev_data->file_mutex));
-
- return retval;
-}
-
-/*
- * rmidev_open: enable access to rmi device
- * @inp: inode struture
- * @filp: file structure
- */
-static int rmidev_open(struct inode *inp, struct file *filp)
-{
- int retval = 0;
- struct rmidev_data *dev_data =
- container_of(inp->i_cdev, struct rmidev_data, main_dev);
-
- if (!dev_data)
- return -EACCES;
-
- filp->private_data = dev_data;
-
- mutex_lock(&(dev_data->file_mutex));
-
- rmidev->fn_ptr->enable(rmidev->rmi4_data, false);
- dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
- "%s: Attention interrupt disabled\n",
- __func__);
-
- if (dev_data->ref_count < 1)
- dev_data->ref_count++;
- else
- retval = -EACCES;
-
- mutex_unlock(&(dev_data->file_mutex));
-
- return retval;
-}
-
-/*
- * rmidev_release: - release access to rmi device
- * @inp: inode structure
- * @filp: file structure
- */
-static int rmidev_release(struct inode *inp, struct file *filp)
-{
- struct rmidev_data *dev_data =
- container_of(inp->i_cdev, struct rmidev_data, main_dev);
-
- if (!dev_data)
- return -EACCES;
-
- mutex_lock(&(dev_data->file_mutex));
-
- dev_data->ref_count--;
- if (dev_data->ref_count < 0)
- dev_data->ref_count = 0;
-
- rmidev->fn_ptr->enable(rmidev->rmi4_data, true);
- dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
- "%s: Attention interrupt enabled\n",
- __func__);
-
- mutex_unlock(&(dev_data->file_mutex));
-
- return 0;
-}
-
-static const struct file_operations rmidev_fops = {
- .owner = THIS_MODULE,
- .llseek = rmidev_llseek,
- .read = rmidev_read,
- .write = rmidev_write,
- .open = rmidev_open,
- .release = rmidev_release,
-};
-
-static void rmidev_device_cleanup(struct rmidev_data *dev_data)
-{
- dev_t devno;
-
- if (dev_data) {
- devno = dev_data->main_dev.dev;
-
- if (dev_data->device_class)
- device_destroy(dev_data->device_class, devno);
-
- cdev_del(&dev_data->main_dev);
-
- unregister_chrdev_region(devno, 1);
-
- dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
- "%s: rmidev device removed\n",
- __func__);
- }
-
- return;
-}
-
-static char *rmi_char_devnode(struct device *dev, mode_t *mode)
-{
- if (!mode)
- return NULL;
-
- *mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
-
- return kasprintf(GFP_KERNEL, "rmi/%s", dev_name(dev));
-}
-
-static int rmidev_create_device_class(void)
-{
- rmidev_device_class = class_create(THIS_MODULE, DEVICE_CLASS_NAME);
-
- if (IS_ERR(rmidev_device_class)) {
- pr_err("%s: Failed to create /dev/%s\n",
- __func__, CHAR_DEVICE_NAME);
- return -ENODEV;
- }
-
- rmidev_device_class->devnode = rmi_char_devnode;
-
- return 0;
-}
-
-static int rmidev_init_device(struct synaptics_rmi4_data *rmi4_data)
-{
- int retval;
- dev_t dev_no;
- unsigned char attr_count;
- struct rmidev_data *dev_data;
- struct device *device_ptr;
-
- rmidev = kzalloc(sizeof(*rmidev), GFP_KERNEL);
- if (!rmidev) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to alloc mem for rmidev\n",
- __func__);
- retval = -ENOMEM;
- goto err_rmidev;
- }
-
- rmidev->fn_ptr = kzalloc(sizeof(*(rmidev->fn_ptr)), GFP_KERNEL);
- if (!rmidev) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to alloc mem for fn_ptr\n",
- __func__);
- retval = -ENOMEM;
- goto err_fn_ptr;
- }
-
- rmidev->fn_ptr->read = rmi4_data->i2c_read;
- rmidev->fn_ptr->write = rmi4_data->i2c_write;
- rmidev->fn_ptr->enable = rmi4_data->irq_enable;
- rmidev->rmi4_data = rmi4_data;
-
- retval = rmidev_create_device_class();
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to create device class\n",
- __func__);
- goto err_device_class;
- }
-
- if (rmidev_major_num) {
- dev_no = MKDEV(rmidev_major_num, DEV_NUMBER);
- retval = register_chrdev_region(dev_no, 1, CHAR_DEVICE_NAME);
- } else {
- retval = alloc_chrdev_region(&dev_no, 0, 1, CHAR_DEVICE_NAME);
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to allocate char device region\n",
- __func__);
- goto err_device_region;
- }
-
- rmidev_major_num = MAJOR(dev_no);
- dev_dbg(&rmi4_data->i2c_client->dev,
- "%s: Major number of rmidev = %d\n",
- __func__, rmidev_major_num);
- }
-
- dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL);
- if (!dev_data) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to alloc mem for dev_data\n",
- __func__);
- retval = -ENOMEM;
- goto err_dev_data;
- }
-
- mutex_init(&dev_data->file_mutex);
- dev_data->rmi_dev = rmidev;
- rmidev->data = dev_data;
-
- cdev_init(&dev_data->main_dev, &rmidev_fops);
-
- retval = cdev_add(&dev_data->main_dev, dev_no, 1);
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to add rmi char device\n",
- __func__);
- goto err_char_device;
- }
-
- dev_set_name(&rmidev->dev, "rmidev%d", MINOR(dev_no));
- dev_data->device_class = rmidev_device_class;
-
- device_ptr = device_create(dev_data->device_class, NULL, dev_no,
- NULL, CHAR_DEVICE_NAME"%d", MINOR(dev_no));
- if (IS_ERR(device_ptr)) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to create rmi char device\n",
- __func__);
- retval = -ENODEV;
- goto err_char_device;
- }
-
- retval = gpio_export(rmi4_data->board->irq_gpio, false);
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to export attention gpio\n",
- __func__);
- } else {
- retval = gpio_export_link(&(rmi4_data->input_dev->dev),
- "attn", rmi4_data->board->irq_gpio);
- if (retval < 0) {
- dev_err(&rmi4_data->input_dev->dev,
- "%s Failed to create gpio symlink\n",
- __func__);
- } else {
- dev_dbg(&rmi4_data->input_dev->dev,
- "%s: Exported attention gpio %d\n",
- __func__, rmi4_data->board->irq_gpio);
- }
- }
-
- rmidev->sysfs_dir = kobject_create_and_add("rmidev",
- &rmi4_data->input_dev->dev.kobj);
- if (!rmidev->sysfs_dir) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to create sysfs directory\n",
- __func__);
- goto err_sysfs_dir;
- }
-
- for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
- retval = sysfs_create_file(rmidev->sysfs_dir,
- &attrs[attr_count].attr);
- if (retval < 0) {
- dev_err(&rmi4_data->input_dev->dev,
- "%s: Failed to create sysfs attributes\n",
- __func__);
- retval = -ENODEV;
- goto err_sysfs_attrs;
- }
- }
-
- return 0;
-
-err_sysfs_attrs:
- for (attr_count--; attr_count >= 0; attr_count--) {
- sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
- &attrs[attr_count].attr);
- }
-
- kobject_put(rmidev->sysfs_dir);
-
-err_sysfs_dir:
-err_char_device:
- rmidev_device_cleanup(dev_data);
- kfree(dev_data);
-
-err_dev_data:
- unregister_chrdev_region(dev_no, 1);
-
-err_device_region:
- class_destroy(rmidev_device_class);
-
-err_device_class:
- kfree(rmidev->fn_ptr);
-
-err_fn_ptr:
- kfree(rmidev);
-
-err_rmidev:
- return retval;
-}
-
-static void rmidev_remove_device(struct synaptics_rmi4_data *rmi4_data)
-{
- unsigned char attr_count;
- struct rmidev_data *dev_data;
-
- if (!rmidev)
- return;
-
- for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++)
- sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr);
-
- kobject_put(rmidev->sysfs_dir);
-
- dev_data = rmidev->data;
- if (dev_data) {
- rmidev_device_cleanup(dev_data);
- kfree(dev_data);
- }
-
- unregister_chrdev_region(rmidev->dev_no, 1);
-
- class_destroy(rmidev_device_class);
-
- kfree(rmidev->fn_ptr);
- kfree(rmidev);
-
- complete(&remove_complete);
-
- return;
-}
-
-static int __init rmidev_module_init(void)
-{
- synaptics_rmi4_new_function(RMI_DEV, true,
- rmidev_init_device,
- rmidev_remove_device,
- NULL);
- return 0;
-}
-
-static void __exit rmidev_module_exit(void)
-{
- init_completion(&remove_complete);
- synaptics_rmi4_new_function(RMI_DEV, false,
- rmidev_init_device,
- rmidev_remove_device,
- NULL);
- wait_for_completion(&remove_complete);
- return;
-}
-
-module_init(rmidev_module_init);
-module_exit(rmidev_module_exit);
-
-MODULE_AUTHOR("Synaptics, Inc.");
-MODULE_DESCRIPTION("RMI4 RMI_Dev Module");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(SYNAPTICS_RMI4_DRIVER_VERSION);
diff --git a/kernel/include/linux/input/synaptics_dsx.h b/kernel/include/linux/input/synaptics_dsx.h
deleted file mode 100644
index b779e42a9bac..000000000000
--- a/kernel/include/linux/input/synaptics_dsx.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Synaptics RMI4 touchscreen driver
- *
- * Copyright (C) 2012 Synaptics Incorporated
- *
- * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
- * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef _SYNAPTICS_DSX_H_
-#define _SYNAPTICS_DSX_H_
-
-/*
- * struct synaptics_rmi4_capacitance_button_map - 0d button map
- * @nbuttons: number of buttons
- * @map: button map
- */
-struct synaptics_rmi4_capacitance_button_map {
- unsigned char nbuttons;
- unsigned char *map;
-};
-
-/*
- * struct synaptics_rmi4_platform_data - rmi4 platform data
- * @x_flip: x flip flag
- * @y_flip: y flip flag
- * @regulator_en: regulator enable flag
- * @irq_gpio: attention interrupt gpio
- * @irq_flags: flags used by the irq
- * @reset_gpio: reset gpio
- * @panel_x: panel maximum values on the x
- * @panel_y: panel maximum values on the y
- * @gpio_config: pointer to gpio configuration function
- * @capacitance_button_map: pointer to 0d button map
- */
-struct synaptics_rmi4_platform_data {
- bool x_flip;
- bool y_flip;
- bool regulator_en;
- unsigned irq_gpio;
- unsigned long irq_flags;
- unsigned reset_gpio;
- unsigned panel_x;
- unsigned panel_y;
- int (*gpio_config)(unsigned gpio, bool configure);
- struct synaptics_rmi4_capacitance_button_map *capacitance_button_map;
-};
-
-#endif
diff --git a/kernel/sched/Makefile b/kernel/sched/Makefile
index 7d0d34c53e08..7c0382a3eace 100644
--- a/kernel/sched/Makefile
+++ b/kernel/sched/Makefile
@@ -15,7 +15,7 @@ obj-y += core.o loadavg.o clock.o cputime.o
obj-y += idle_task.o fair.o rt.o deadline.o stop_task.o
obj-y += wait.o completion.o idle.o sched_avg.o
obj-$(CONFIG_SMP) += cpupri.o cpudeadline.o
-obj-$(CONFIG_SCHED_HMP) += hmp.o
+obj-$(CONFIG_SCHED_HMP) += hmp.o boost.o
obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o
obj-$(CONFIG_SCHEDSTATS) += stats.o
obj-$(CONFIG_SCHED_DEBUG) += debug.o
diff --git a/kernel/sched/boost.c b/kernel/sched/boost.c
new file mode 100644
index 000000000000..fcfda385b74a
--- /dev/null
+++ b/kernel/sched/boost.c
@@ -0,0 +1,226 @@
+/* Copyright (c) 2012-2016, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "sched.h"
+#include <linux/of.h>
+#include <linux/sched/core_ctl.h>
+#include <trace/events/sched.h>
+
+/*
+ * Scheduler boost is a mechanism to temporarily place tasks on CPUs
+ * with higher capacity than those where a task would have normally
+ * ended up with their load characteristics. Any entity enabling
+ * boost is responsible for disabling it as well.
+ */
+
+unsigned int sysctl_sched_boost;
+static enum sched_boost_policy boost_policy;
+static enum sched_boost_policy boost_policy_dt = SCHED_BOOST_NONE;
+static DEFINE_MUTEX(boost_mutex);
+static unsigned int freq_aggr_threshold_backup;
+
+static inline void boost_kick(int cpu)
+{
+ struct rq *rq = cpu_rq(cpu);
+
+ if (!test_and_set_bit(BOOST_KICK, &rq->hmp_flags))
+ smp_send_reschedule(cpu);
+}
+
+static void boost_kick_cpus(void)
+{
+ int i;
+ struct cpumask kick_mask;
+
+ if (boost_policy != SCHED_BOOST_ON_BIG)
+ return;
+
+ cpumask_andnot(&kick_mask, cpu_online_mask, cpu_isolated_mask);
+
+ for_each_cpu(i, &kick_mask) {
+ if (cpu_capacity(i) != max_capacity)
+ boost_kick(i);
+ }
+}
+
+int got_boost_kick(void)
+{
+ int cpu = smp_processor_id();
+ struct rq *rq = cpu_rq(cpu);
+
+ return test_bit(BOOST_KICK, &rq->hmp_flags);
+}
+
+void clear_boost_kick(int cpu)
+{
+ struct rq *rq = cpu_rq(cpu);
+
+ clear_bit(BOOST_KICK, &rq->hmp_flags);
+}
+
+/*
+ * Scheduler boost type and boost policy might at first seem unrelated,
+ * however, there exists a connection between them that will allow us
+ * to use them interchangeably during placement decisions. We'll explain
+ * the connection here in one possible way so that the implications are
+ * clear when looking at placement policies.
+ *
+ * When policy = SCHED_BOOST_NONE, type is either none or RESTRAINED
+ * When policy = SCHED_BOOST_ON_ALL or SCHED_BOOST_ON_BIG, type can
+ * neither be none nor RESTRAINED.
+ */
+static void set_boost_policy(int type)
+{
+ if (type == SCHED_BOOST_NONE || type == RESTRAINED_BOOST) {
+ boost_policy = SCHED_BOOST_NONE;
+ return;
+ }
+
+ if (boost_policy_dt) {
+ boost_policy = boost_policy_dt;
+ return;
+ }
+
+ if (min_possible_efficiency != max_possible_efficiency) {
+ boost_policy = SCHED_BOOST_ON_BIG;
+ return;
+ }
+
+ boost_policy = SCHED_BOOST_ON_ALL;
+}
+
+enum sched_boost_policy sched_boost_policy(void)
+{
+ return boost_policy;
+}
+
+static bool verify_boost_params(int old_val, int new_val)
+{
+ /*
+ * Boost can only be turned on or off. There is no possiblity of
+ * switching from one boost type to another or to set the same
+ * kind of boost several times.
+ */
+ return !(!!old_val == !!new_val);
+}
+
+static void _sched_set_boost(int old_val, int type)
+{
+ switch (type) {
+ case NO_BOOST:
+ if (old_val == FULL_THROTTLE_BOOST)
+ core_ctl_set_boost(false);
+ else if (old_val == CONSERVATIVE_BOOST)
+ restore_cgroup_boost_settings();
+ else
+ update_freq_aggregate_threshold(
+ freq_aggr_threshold_backup);
+ break;
+
+ case FULL_THROTTLE_BOOST:
+ core_ctl_set_boost(true);
+ boost_kick_cpus();
+ break;
+
+ case CONSERVATIVE_BOOST:
+ update_cgroup_boost_settings();
+ boost_kick_cpus();
+ break;
+
+ case RESTRAINED_BOOST:
+ freq_aggr_threshold_backup =
+ update_freq_aggregate_threshold(1);
+ break;
+
+ default:
+ WARN_ON(1);
+ return;
+ }
+
+ set_boost_policy(type);
+ sysctl_sched_boost = type;
+ trace_sched_set_boost(type);
+}
+
+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;
+
+ if (!of_property_read_string(sn, "boost-policy", &boost_policy)) {
+ if (!strcmp(boost_policy, "boost-on-big"))
+ boost_policy_dt = SCHED_BOOST_ON_BIG;
+ else if (!strcmp(boost_policy, "boost-on-all"))
+ boost_policy_dt = SCHED_BOOST_ON_ALL;
+ }
+}
+
+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))
+ _sched_set_boost(sysctl_sched_boost, type);
+ else
+ ret = -EINVAL;
+
+ mutex_unlock(&boost_mutex);
+ return ret;
+}
+
+int sched_boost_handler(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos)
+{
+ int ret;
+ unsigned int *data = (unsigned int *)table->data;
+ unsigned int old_val;
+
+ if (!sched_enable_hmp)
+ return -EINVAL;
+
+ mutex_lock(&boost_mutex);
+
+ old_val = *data;
+ ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+
+ if (ret || !write)
+ goto done;
+
+ if (verify_boost_params(old_val, *data)) {
+ _sched_set_boost(old_val, *data);
+ } else {
+ *data = old_val;
+ ret = -EINVAL;
+ }
+
+done:
+ mutex_unlock(&boost_mutex);
+ return ret;
+}
+
+int sched_boost(void)
+{
+ return sysctl_sched_boost;
+}
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index e7196c3a3457..a5d101e8a5f2 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5497,7 +5497,7 @@ static void migrate_tasks(struct rq *dead_rq, bool migrate_pinned_tasks)
*/
if ((migrate_pinned_tasks && rq->nr_running == 1) ||
(!migrate_pinned_tasks &&
- rq->nr_running == num_pinned_kthreads))
+ rq->nr_running <= num_pinned_kthreads))
break;
/*
@@ -5533,8 +5533,12 @@ static void migrate_tasks(struct rq *dead_rq, bool migrate_pinned_tasks)
* Since we're inside stop-machine, _nothing_ should have
* changed the task, WARN if weird stuff happened, because in
* that case the above rq->lock drop is a fail too.
+ * However, during cpu isolation the load balancer might have
+ * interferred since we don't stop all CPUs. Ignore warning for
+ * this case.
*/
- if (WARN_ON(task_rq(next) != rq || !task_on_rq_queued(next))) {
+ if (task_rq(next) != rq || !task_on_rq_queued(next)) {
+ WARN_ON(migrate_pinned_tasks);
raw_spin_unlock(&next->pi_lock);
continue;
}
@@ -7842,7 +7846,6 @@ void __init sched_init_smp(void)
hotcpu_notifier(cpuset_cpu_inactive, CPU_PRI_CPUSET_INACTIVE);
update_cluster_topology();
- init_sched_hmp_boost_policy();
init_hrtick();
@@ -7891,7 +7894,7 @@ void __init sched_init(void)
BUG_ON(num_possible_cpus() > BITS_PER_LONG);
- sched_hmp_parse_dt();
+ sched_boost_parse_dt();
init_clusters();
#ifdef CONFIG_FAIR_GROUP_SCHED
diff --git a/kernel/sched/core_ctl.c b/kernel/sched/core_ctl.c
index 0db85a4fa9c8..9b21a09ec4ba 100644
--- a/kernel/sched/core_ctl.c
+++ b/kernel/sched/core_ctl.c
@@ -687,6 +687,7 @@ int core_ctl_set_boost(bool boost)
return ret;
}
+EXPORT_SYMBOL(core_ctl_set_boost);
void core_ctl_check(u64 wallclock)
{
@@ -719,8 +720,18 @@ static void move_cpu_lru(struct cpu_data *cpu_data)
static void try_to_isolate(struct cluster_data *cluster, unsigned int need)
{
struct cpu_data *c, *tmp;
+ unsigned long flags;
+ unsigned int num_cpus = cluster->num_cpus;
+ /*
+ * Protect against entry being removed (and added at tail) by other
+ * thread (hotplug).
+ */
+ spin_lock_irqsave(&state_lock, flags);
list_for_each_entry_safe(c, tmp, &cluster->lru, sib) {
+ if (!num_cpus--)
+ break;
+
if (!is_active(c))
continue;
if (cluster->active_cpus == need)
@@ -729,6 +740,8 @@ static void try_to_isolate(struct cluster_data *cluster, unsigned int need)
if (c->is_busy)
continue;
+ spin_unlock_irqrestore(&state_lock, flags);
+
pr_debug("Trying to isolate CPU%u\n", c->cpu);
if (!sched_isolate_cpu(c->cpu)) {
c->isolated_by_us = true;
@@ -738,7 +751,9 @@ static void try_to_isolate(struct cluster_data *cluster, unsigned int need)
pr_debug("Unable to isolate CPU%u\n", c->cpu);
}
cluster->active_cpus = get_active_cpu_count(cluster);
+ spin_lock_irqsave(&state_lock, flags);
}
+ spin_unlock_irqrestore(&state_lock, flags);
/*
* If the number of active CPUs is within the limits, then
@@ -747,12 +762,19 @@ static void try_to_isolate(struct cluster_data *cluster, unsigned int need)
if (cluster->active_cpus <= cluster->max_cpus)
return;
+ num_cpus = cluster->num_cpus;
+ spin_lock_irqsave(&state_lock, flags);
list_for_each_entry_safe(c, tmp, &cluster->lru, sib) {
+ if (!num_cpus--)
+ break;
+
if (!is_active(c))
continue;
if (cluster->active_cpus <= cluster->max_cpus)
break;
+ spin_unlock_irqrestore(&state_lock, flags);
+
pr_debug("Trying to isolate CPU%u\n", c->cpu);
if (!sched_isolate_cpu(c->cpu)) {
c->isolated_by_us = true;
@@ -762,15 +784,28 @@ static void try_to_isolate(struct cluster_data *cluster, unsigned int need)
pr_debug("Unable to isolate CPU%u\n", c->cpu);
}
cluster->active_cpus = get_active_cpu_count(cluster);
+ spin_lock_irqsave(&state_lock, flags);
}
+ spin_unlock_irqrestore(&state_lock, flags);
+
}
static void __try_to_unisolate(struct cluster_data *cluster,
unsigned int need, bool force)
{
struct cpu_data *c, *tmp;
+ unsigned long flags;
+ unsigned int num_cpus = cluster->num_cpus;
+ /*
+ * Protect against entry being removed (and added at tail) by other
+ * thread (hotplug).
+ */
+ spin_lock_irqsave(&state_lock, flags);
list_for_each_entry_safe(c, tmp, &cluster->lru, sib) {
+ if (!num_cpus--)
+ break;
+
if (!c->isolated_by_us)
continue;
if ((c->online && !cpu_isolated(c->cpu)) ||
@@ -779,6 +814,8 @@ static void __try_to_unisolate(struct cluster_data *cluster,
if (cluster->active_cpus == need)
break;
+ spin_unlock_irqrestore(&state_lock, flags);
+
pr_debug("Trying to unisolate CPU%u\n", c->cpu);
if (!sched_unisolate_cpu(c->cpu)) {
c->isolated_by_us = false;
@@ -787,7 +824,9 @@ static void __try_to_unisolate(struct cluster_data *cluster,
pr_debug("Unable to unisolate CPU%u\n", c->cpu);
}
cluster->active_cpus = get_active_cpu_count(cluster);
+ spin_lock_irqsave(&state_lock, flags);
}
+ spin_unlock_irqrestore(&state_lock, flags);
}
static void try_to_unisolate(struct cluster_data *cluster, unsigned int need)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 1674b1054f83..3db77aff2433 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -2596,6 +2596,7 @@ static u32 __compute_runnable_contrib(u64 n)
#define SBC_FLAG_COLOC_CLUSTER 0x10000
#define SBC_FLAG_WAKER_CLUSTER 0x20000
#define SBC_FLAG_BACKUP_CLUSTER 0x40000
+#define SBC_FLAG_BOOST_CLUSTER 0x80000
struct cpu_select_env {
struct task_struct *p;
@@ -2605,7 +2606,7 @@ struct cpu_select_env {
u8 need_waker_cluster:1;
u8 sync:1;
u8 ignore_prev_cpu:1;
- enum sched_boost_type boost_type;
+ enum sched_boost_policy boost_policy;
int prev_cpu;
DECLARE_BITMAP(candidate_list, NR_CPUS);
DECLARE_BITMAP(backup_list, NR_CPUS);
@@ -2705,10 +2706,38 @@ select_least_power_cluster(struct cpu_select_env *env)
struct sched_cluster *cluster;
if (env->rtg) {
- env->task_load = scale_load_to_cpu(task_load(env->p),
- cluster_first_cpu(env->rtg->preferred_cluster));
- env->sbc_best_cluster_flag |= SBC_FLAG_COLOC_CLUSTER;
- return env->rtg->preferred_cluster;
+ int cpu = cluster_first_cpu(env->rtg->preferred_cluster);
+
+ env->task_load = scale_load_to_cpu(task_load(env->p), cpu);
+
+ if (task_load_will_fit(env->p, env->task_load,
+ cpu, env->boost_policy)) {
+ env->sbc_best_cluster_flag |= SBC_FLAG_COLOC_CLUSTER;
+
+ if (env->boost_policy == SCHED_BOOST_NONE)
+ return env->rtg->preferred_cluster;
+
+ for_each_sched_cluster(cluster) {
+ if (cluster != env->rtg->preferred_cluster) {
+ __set_bit(cluster->id,
+ env->backup_list);
+ __clear_bit(cluster->id,
+ env->candidate_list);
+ }
+ }
+
+ return env->rtg->preferred_cluster;
+ }
+
+ /*
+ * Since the task load does not fit on the preferred
+ * cluster anymore, pretend that the task does not
+ * have any preferred cluster. This allows the waking
+ * task to get the appropriate CPU it needs as per the
+ * non co-location placement policy without having to
+ * wait until the preferred cluster is updated.
+ */
+ env->rtg = NULL;
}
for_each_sched_cluster(cluster) {
@@ -2718,7 +2747,7 @@ select_least_power_cluster(struct cpu_select_env *env)
env->task_load = scale_load_to_cpu(task_load(env->p),
cpu);
if (task_load_will_fit(env->p, env->task_load, cpu,
- env->boost_type))
+ env->boost_policy))
return cluster;
__set_bit(cluster->id, env->backup_list);
@@ -2961,7 +2990,14 @@ static void find_best_cpu_in_cluster(struct sched_cluster *c,
update_spare_capacity(stats, env, i, c->capacity,
env->cpu_load);
- if (env->boost_type == SCHED_BOOST_ON_ALL ||
+ /*
+ * need_idle takes precedence over sched boost but when both
+ * are set, idlest CPU with in all the clusters is selected
+ * when boost_policy = BOOST_ON_ALL whereas idlest CPU in the
+ * big cluster is selected within boost_policy = BOOST_ON_BIG.
+ */
+ if ((!env->need_idle &&
+ env->boost_policy != SCHED_BOOST_NONE) ||
env->need_waker_cluster ||
sched_cpu_high_irqload(i) ||
spill_threshold_crossed(env, cpu_rq(i)))
@@ -3005,7 +3041,7 @@ bias_to_prev_cpu(struct cpu_select_env *env, struct cluster_cpu_stats *stats)
struct task_struct *task = env->p;
struct sched_cluster *cluster;
- if (env->boost_type != SCHED_BOOST_NONE || env->reason ||
+ if (env->boost_policy != SCHED_BOOST_NONE || env->reason ||
!task->ravg.mark_start ||
env->need_idle || !sched_short_sleep_task_threshold)
return false;
@@ -3034,7 +3070,7 @@ bias_to_prev_cpu(struct cpu_select_env *env, struct cluster_cpu_stats *stats)
cluster = cpu_rq(prev_cpu)->cluster;
if (!task_load_will_fit(task, env->task_load, prev_cpu,
- sched_boost_type())) {
+ sched_boost_policy())) {
__set_bit(cluster->id, env->backup_list);
__clear_bit(cluster->id, env->candidate_list);
@@ -3056,7 +3092,7 @@ bias_to_prev_cpu(struct cpu_select_env *env, struct cluster_cpu_stats *stats)
static inline bool
wake_to_waker_cluster(struct cpu_select_env *env)
{
- return env->boost_type == SCHED_BOOST_NONE &&
+ return env->boost_policy == SCHED_BOOST_NONE &&
!env->need_idle && !env->reason && env->sync &&
task_load(current) > sched_big_waker_task_load &&
task_load(env->p) < sched_small_wakee_task_load;
@@ -3098,7 +3134,6 @@ static int select_best_cpu(struct task_struct *p, int target, int reason,
.reason = reason,
.need_idle = wake_to_idle(p),
.need_waker_cluster = 0,
- .boost_type = sched_boost_type(),
.sync = sync,
.prev_cpu = target,
.ignore_prev_cpu = 0,
@@ -3107,6 +3142,9 @@ static int select_best_cpu(struct task_struct *p, int target, int reason,
.sbc_best_cluster_flag = 0,
};
+ env.boost_policy = task_sched_boost(p) ?
+ sched_boost_policy() : SCHED_BOOST_NONE;
+
bitmap_copy(env.candidate_list, all_cluster_ids, NR_CPUS);
bitmap_zero(env.backup_list, NR_CPUS);
@@ -3178,12 +3216,23 @@ retry:
sbc_flag |= env.sbc_best_flag;
target = stats.best_cpu;
} else {
- if (env.rtg) {
+ if (env.rtg && env.boost_policy == SCHED_BOOST_NONE) {
env.rtg = NULL;
goto retry;
}
- find_backup_cluster(&env, &stats);
+ /*
+ * With boost_policy == SCHED_BOOST_ON_BIG, we reach here with
+ * backup_list = little cluster, candidate_list = none and
+ * stats->best_capacity_cpu points the best spare capacity
+ * CPU among the CPUs in the big cluster.
+ */
+ if (env.boost_policy == SCHED_BOOST_ON_BIG &&
+ stats.best_capacity_cpu >= 0)
+ sbc_flag |= SBC_FLAG_BOOST_CLUSTER;
+ else
+ find_backup_cluster(&env, &stats);
+
if (stats.best_capacity_cpu >= 0) {
target = stats.best_capacity_cpu;
sbc_flag |= SBC_FLAG_BEST_CAP_CPU;
@@ -3193,8 +3242,8 @@ retry:
out:
sbc_flag |= env.sbc_best_cluster_flag;
rcu_read_unlock();
- trace_sched_task_load(p, sched_boost(), env.reason, env.sync,
- env.need_idle, sbc_flag, target);
+ trace_sched_task_load(p, sched_boost_policy() && task_sched_boost(p),
+ env.reason, env.sync, env.need_idle, sbc_flag, target);
return target;
}
@@ -3402,11 +3451,9 @@ static inline int migration_needed(struct task_struct *p, int cpu)
if (task_will_be_throttled(p))
return 0;
- if (sched_boost_type() == SCHED_BOOST_ON_BIG) {
- if (cpu_capacity(cpu) != max_capacity)
- return UP_MIGRATION;
- return 0;
- }
+ if (sched_boost_policy() == SCHED_BOOST_ON_BIG &&
+ cpu_capacity(cpu) != max_capacity && task_sched_boost(p))
+ return UP_MIGRATION;
if (sched_cpu_high_irqload(cpu))
return IRQLOAD_MIGRATION;
@@ -3420,7 +3467,7 @@ static inline int migration_needed(struct task_struct *p, int cpu)
return DOWN_MIGRATION;
}
- if (!grp && !task_will_fit(p, cpu)) {
+ if (!task_will_fit(p, cpu)) {
rcu_read_unlock();
return UP_MIGRATION;
}
@@ -6648,10 +6695,7 @@ enum fbq_type { regular, remote, all };
#define LBF_NEED_BREAK 0x02
#define LBF_DST_PINNED 0x04
#define LBF_SOME_PINNED 0x08
-#define LBF_SCHED_BOOST_ACTIVE_BALANCE 0x40
#define LBF_BIG_TASK_ACTIVE_BALANCE 0x80
-#define LBF_HMP_ACTIVE_BALANCE (LBF_SCHED_BOOST_ACTIVE_BALANCE | \
- LBF_BIG_TASK_ACTIVE_BALANCE)
#define LBF_IGNORE_BIG_TASKS 0x100
#define LBF_IGNORE_PREFERRED_CLUSTER_TASKS 0x200
#define LBF_MOVED_RELATED_THREAD_GROUP_TASK 0x400
@@ -6682,6 +6726,7 @@ struct lb_env {
enum fbq_type fbq_type;
struct list_head tasks;
+ enum sched_boost_policy boost_policy;
};
/*
@@ -6826,9 +6871,14 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env)
/* Record that we found atleast one task that could run on dst_cpu */
env->flags &= ~LBF_ALL_PINNED;
- if (cpu_capacity(env->dst_cpu) > cpu_capacity(env->src_cpu) &&
- nr_big_tasks(env->src_rq) && !is_big_task(p))
- return 0;
+ if (cpu_capacity(env->dst_cpu) > cpu_capacity(env->src_cpu)) {
+ if (nr_big_tasks(env->src_rq) && !is_big_task(p))
+ return 0;
+
+ if (env->boost_policy == SCHED_BOOST_ON_BIG &&
+ !task_sched_boost(p))
+ return 0;
+ }
twf = task_will_fit(p, env->dst_cpu);
@@ -6951,8 +7001,7 @@ static int detach_tasks(struct lb_env *env)
if (env->imbalance <= 0)
return 0;
- if (cpu_capacity(env->dst_cpu) < cpu_capacity(env->src_cpu) &&
- !sched_boost())
+ if (cpu_capacity(env->dst_cpu) < cpu_capacity(env->src_cpu))
env->flags |= LBF_IGNORE_BIG_TASKS;
else if (!same_cluster(env->dst_cpu, env->src_cpu))
env->flags |= LBF_IGNORE_PREFERRED_CLUSTER_TASKS;
@@ -7255,8 +7304,10 @@ bail_inter_cluster_balance(struct lb_env *env, struct sd_lb_stats *sds)
int local_capacity, busiest_capacity;
int local_pwr_cost, busiest_pwr_cost;
int nr_cpus;
+ int boost = sched_boost();
- if (!sysctl_sched_restrict_cluster_spill || sched_boost())
+ if (!sysctl_sched_restrict_cluster_spill ||
+ boost == FULL_THROTTLE_BOOST || boost == CONSERVATIVE_BOOST)
return 0;
local_cpu = group_first_cpu(sds->local);
@@ -7628,11 +7679,6 @@ static bool update_sd_pick_busiest_active_balance(struct lb_env *env,
{
if (env->idle != CPU_NOT_IDLE &&
cpu_capacity(env->dst_cpu) > group_rq_capacity(sg)) {
- if (sched_boost() && !sds->busiest && sgs->sum_nr_running) {
- env->flags |= LBF_SCHED_BOOST_ACTIVE_BALANCE;
- return true;
- }
-
if (sgs->sum_nr_big_tasks >
sds->busiest_stat.sum_nr_big_tasks) {
env->flags |= LBF_BIG_TASK_ACTIVE_BALANCE;
@@ -8045,7 +8091,7 @@ static struct sched_group *find_busiest_group(struct lb_env *env)
if (!sds.busiest || busiest->sum_nr_running == 0)
goto out_balanced;
- if (env->flags & LBF_HMP_ACTIVE_BALANCE)
+ if (env->flags & LBF_BIG_TASK_ACTIVE_BALANCE)
goto force_balance;
if (bail_inter_cluster_balance(env, &sds))
@@ -8257,7 +8303,7 @@ static int need_active_balance(struct lb_env *env)
{
struct sched_domain *sd = env->sd;
- if (env->flags & LBF_HMP_ACTIVE_BALANCE)
+ if (env->flags & LBF_BIG_TASK_ACTIVE_BALANCE)
return 1;
if (env->idle == CPU_NEWLY_IDLE) {
@@ -8348,20 +8394,21 @@ static int load_balance(int this_cpu, struct rq *this_rq,
struct cpumask *cpus = this_cpu_cpumask_var_ptr(load_balance_mask);
struct lb_env env = {
- .sd = sd,
- .dst_cpu = this_cpu,
- .dst_rq = this_rq,
- .dst_grpmask = sched_group_cpus(sd->groups),
- .idle = idle,
- .loop_break = sched_nr_migrate_break,
- .cpus = cpus,
- .fbq_type = all,
- .tasks = LIST_HEAD_INIT(env.tasks),
- .imbalance = 0,
- .flags = 0,
- .loop = 0,
+ .sd = sd,
+ .dst_cpu = this_cpu,
+ .dst_rq = this_rq,
+ .dst_grpmask = sched_group_cpus(sd->groups),
+ .idle = idle,
+ .loop_break = sched_nr_migrate_break,
+ .cpus = cpus,
+ .fbq_type = all,
+ .tasks = LIST_HEAD_INIT(env.tasks),
+ .imbalance = 0,
+ .flags = 0,
+ .loop = 0,
.busiest_nr_running = 0,
.busiest_grp_capacity = 0,
+ .boost_policy = sched_boost_policy(),
};
/*
@@ -8510,7 +8557,7 @@ more_balance:
no_move:
if (!ld_moved) {
- if (!(env.flags & LBF_HMP_ACTIVE_BALANCE))
+ if (!(env.flags & LBF_BIG_TASK_ACTIVE_BALANCE))
schedstat_inc(sd, lb_failed[idle]);
/*
@@ -8520,7 +8567,7 @@ no_move:
* excessive cache_hot migrations and active balances.
*/
if (idle != CPU_NEWLY_IDLE &&
- !(env.flags & LBF_HMP_ACTIVE_BALANCE))
+ !(env.flags & LBF_BIG_TASK_ACTIVE_BALANCE))
sd->nr_balance_failed++;
if (need_active_balance(&env)) {
@@ -8797,6 +8844,7 @@ static int active_load_balance_cpu_stop(void *data)
.busiest_grp_capacity = 0,
.flags = 0,
.loop = 0,
+ .boost_policy = sched_boost_policy(),
};
bool moved = false;
@@ -9272,7 +9320,8 @@ static inline int _nohz_kick_needed_hmp(struct rq *rq, int cpu, int *type)
if (rq->nr_running < 2)
return 0;
- if (!sysctl_sched_restrict_cluster_spill || sched_boost())
+ if (!sysctl_sched_restrict_cluster_spill ||
+ sched_boost_policy() == SCHED_BOOST_ON_ALL)
return 1;
if (cpu_max_power_cost(cpu) == max_power_cost)
diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c
index 30391aae0822..968a41e0e81e 100644
--- a/kernel/sched/hmp.c
+++ b/kernel/sched/hmp.c
@@ -17,8 +17,6 @@
#include <linux/cpufreq.h>
#include <linux/list_sort.h>
#include <linux/syscore_ops.h>
-#include <linux/of.h>
-#include <linux/sched/core_ctl.h>
#include "sched.h"
@@ -231,52 +229,6 @@ fail:
return ret;
}
-/*
- * It is possible that CPUs of the same micro architecture can have slight
- * difference in the efficiency due to other factors like cache size. The
- * BOOST_ON_BIG policy may not be optimial for such systems. The required
- * boost policy can be specified via device tree to handle this.
- */
-static int __read_mostly sched_boost_policy = SCHED_BOOST_NONE;
-
-/*
- * This should be called after clusters are populated and
- * the respective efficiency values are initialized.
- */
-void init_sched_hmp_boost_policy(void)
-{
- /*
- * Initialize the boost type here if it is not passed from
- * device tree.
- */
- if (sched_boost_policy == SCHED_BOOST_NONE) {
- if (max_possible_efficiency != min_possible_efficiency)
- sched_boost_policy = SCHED_BOOST_ON_BIG;
- else
- sched_boost_policy = SCHED_BOOST_ON_ALL;
- }
-}
-
-void sched_hmp_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;
-
- if (!of_property_read_string(sn, "boost-policy", &boost_policy)) {
- if (!strcmp(boost_policy, "boost-on-big"))
- sched_boost_policy = SCHED_BOOST_ON_BIG;
- else if (!strcmp(boost_policy, "boost-on-all"))
- sched_boost_policy = SCHED_BOOST_ON_ALL;
- }
-}
-
unsigned int max_possible_efficiency = 1;
unsigned int min_possible_efficiency = UINT_MAX;
@@ -680,29 +632,6 @@ int __init set_sched_enable_hmp(char *str)
early_param("sched_enable_hmp", set_sched_enable_hmp);
-int got_boost_kick(void)
-{
- int cpu = smp_processor_id();
- struct rq *rq = cpu_rq(cpu);
-
- return test_bit(BOOST_KICK, &rq->hmp_flags);
-}
-
-inline void clear_boost_kick(int cpu)
-{
- struct rq *rq = cpu_rq(cpu);
-
- clear_bit(BOOST_KICK, &rq->hmp_flags);
-}
-
-inline void boost_kick(int cpu)
-{
- struct rq *rq = cpu_rq(cpu);
-
- if (!test_and_set_bit(BOOST_KICK, &rq->hmp_flags))
- smp_send_reschedule(cpu);
-}
-
/* Clear any HMP scheduler related requests pending from or on cpu */
void clear_hmp_request(int cpu)
{
@@ -840,6 +769,9 @@ min_max_possible_capacity = 1024; /* min(rq->max_possible_capacity) */
/* Window size (in ns) */
__read_mostly unsigned int sched_ravg_window = MIN_SCHED_RAVG_WINDOW;
+/* Maximum allowed threshold before freq aggregation must be enabled */
+#define MAX_FREQ_AGGR_THRESH 1000
+
/* Temporarily disable window-stats activity on all cpus */
unsigned int __read_mostly sched_disable_window_stats;
@@ -919,8 +851,8 @@ static const unsigned int top_tasks_bitmap_size =
* C1 busy time = 5 + 5 + 6 = 16ms
*
*/
-static __read_mostly unsigned int sched_freq_aggregate;
-__read_mostly unsigned int sysctl_sched_freq_aggregate;
+static __read_mostly unsigned int sched_freq_aggregate = 1;
+__read_mostly unsigned int sysctl_sched_freq_aggregate = 1;
unsigned int __read_mostly sysctl_sched_freq_aggregate_threshold_pct;
static unsigned int __read_mostly sched_freq_aggregate_threshold;
@@ -937,14 +869,6 @@ unsigned int max_task_load(void)
/* Use this knob to turn on or off HMP-aware task placement logic */
unsigned int __read_mostly sched_enable_hmp;
-/*
- * Scheduler boost is a mechanism to temporarily place tasks on CPUs
- * with higher capacity than those where a task would have normally
- * ended up with their load characteristics. Any entity enabling
- * boost is responsible for disabling it as well.
- */
-unsigned int sysctl_sched_boost;
-
/* A cpu can no longer accommodate more tasks if:
*
* rq->nr_running > sysctl_sched_spill_nr_run ||
@@ -996,6 +920,21 @@ unsigned int __read_mostly sched_downmigrate;
unsigned int __read_mostly sysctl_sched_downmigrate_pct = 60;
/*
+ * Task groups whose aggregate demand on a cpu is more than
+ * sched_group_upmigrate need to be up-migrated if possible.
+ */
+unsigned int __read_mostly sched_group_upmigrate;
+unsigned int __read_mostly sysctl_sched_group_upmigrate_pct = 100;
+
+/*
+ * Task groups, once up-migrated, will need to drop their aggregate
+ * demand to less than sched_group_downmigrate before they are "down"
+ * migrated.
+ */
+unsigned int __read_mostly sched_group_downmigrate;
+unsigned int __read_mostly sysctl_sched_group_downmigrate_pct = 95;
+
+/*
* The load scale factor of a CPU gets boosted when its max frequency
* is restricted due to which the tasks are migrating to higher capacity
* CPUs early. The sched_upmigrate threshold is auto-upgraded by
@@ -1017,33 +956,46 @@ sched_long_cpu_selection_threshold = 100 * NSEC_PER_MSEC;
unsigned int __read_mostly sysctl_sched_restrict_cluster_spill;
-void update_up_down_migrate(void)
+static void
+_update_up_down_migrate(unsigned int *up_migrate, unsigned int *down_migrate)
{
- unsigned int up_migrate = pct_to_real(sysctl_sched_upmigrate_pct);
- unsigned int down_migrate = pct_to_real(sysctl_sched_downmigrate_pct);
unsigned int delta;
if (up_down_migrate_scale_factor == 1024)
- goto done;
+ return;
- delta = up_migrate - down_migrate;
+ delta = *up_migrate - *down_migrate;
- up_migrate /= NSEC_PER_USEC;
- up_migrate *= up_down_migrate_scale_factor;
- up_migrate >>= 10;
- up_migrate *= NSEC_PER_USEC;
+ *up_migrate /= NSEC_PER_USEC;
+ *up_migrate *= up_down_migrate_scale_factor;
+ *up_migrate >>= 10;
+ *up_migrate *= NSEC_PER_USEC;
- up_migrate = min(up_migrate, sched_ravg_window);
+ *up_migrate = min(*up_migrate, sched_ravg_window);
- down_migrate /= NSEC_PER_USEC;
- down_migrate *= up_down_migrate_scale_factor;
- down_migrate >>= 10;
- down_migrate *= NSEC_PER_USEC;
+ *down_migrate /= NSEC_PER_USEC;
+ *down_migrate *= up_down_migrate_scale_factor;
+ *down_migrate >>= 10;
+ *down_migrate *= NSEC_PER_USEC;
- down_migrate = min(down_migrate, up_migrate - delta);
-done:
+ *down_migrate = min(*down_migrate, *up_migrate - delta);
+}
+
+static void update_up_down_migrate(void)
+{
+ unsigned int up_migrate = pct_to_real(sysctl_sched_upmigrate_pct);
+ unsigned int down_migrate = pct_to_real(sysctl_sched_downmigrate_pct);
+
+ _update_up_down_migrate(&up_migrate, &down_migrate);
sched_upmigrate = up_migrate;
sched_downmigrate = down_migrate;
+
+ up_migrate = pct_to_real(sysctl_sched_group_upmigrate_pct);
+ down_migrate = pct_to_real(sysctl_sched_group_downmigrate_pct);
+
+ _update_up_down_migrate(&up_migrate, &down_migrate);
+ sched_group_upmigrate = up_migrate;
+ sched_group_downmigrate = down_migrate;
}
void set_hmp_defaults(void)
@@ -1134,82 +1086,6 @@ u64 cpu_load_sync(int cpu, int sync)
return scale_load_to_cpu(cpu_cravg_sync(cpu, sync), cpu);
}
-static int boost_refcount;
-static DEFINE_SPINLOCK(boost_lock);
-static DEFINE_MUTEX(boost_mutex);
-
-static void boost_kick_cpus(void)
-{
- int i;
-
- for_each_online_cpu(i) {
- if (cpu_capacity(i) != max_capacity)
- boost_kick(i);
- }
-}
-
-int sched_boost(void)
-{
- return boost_refcount > 0;
-}
-
-int sched_set_boost(int enable)
-{
- unsigned long flags;
- int ret = 0;
- int old_refcount;
-
- if (!sched_enable_hmp)
- return -EINVAL;
-
- spin_lock_irqsave(&boost_lock, flags);
-
- old_refcount = boost_refcount;
-
- if (enable == 1) {
- boost_refcount++;
- } else if (!enable) {
- if (boost_refcount >= 1)
- boost_refcount--;
- else
- ret = -EINVAL;
- } else {
- ret = -EINVAL;
- }
-
- if (!old_refcount && boost_refcount)
- boost_kick_cpus();
-
- if (boost_refcount <= 1)
- core_ctl_set_boost(boost_refcount == 1);
- trace_sched_set_boost(boost_refcount);
- spin_unlock_irqrestore(&boost_lock, flags);
-
- return ret;
-}
-
-int sched_boost_handler(struct ctl_table *table, int write,
- void __user *buffer, size_t *lenp,
- loff_t *ppos)
-{
- int ret;
-
- mutex_lock(&boost_mutex);
- if (!write)
- sysctl_sched_boost = sched_boost();
-
- ret = proc_dointvec(table, write, buffer, lenp, ppos);
- if (ret || !write)
- goto done;
-
- ret = (sysctl_sched_boost <= 1) ?
- sched_set_boost(sysctl_sched_boost) : -EINVAL;
-
-done:
- mutex_unlock(&boost_mutex);
- return ret;
-}
-
/*
* Task will fit on a cpu if it's bandwidth consumption on that cpu
* will be less than sched_upmigrate. A big task that was previously
@@ -1219,60 +1095,63 @@ done:
* tasks with load close to the upmigrate threshold
*/
int task_load_will_fit(struct task_struct *p, u64 task_load, int cpu,
- enum sched_boost_type boost_type)
+ enum sched_boost_policy boost_policy)
{
- int upmigrate;
+ int upmigrate = sched_upmigrate;
if (cpu_capacity(cpu) == max_capacity)
return 1;
- if (boost_type != SCHED_BOOST_ON_BIG) {
+ if (cpu_capacity(task_cpu(p)) > cpu_capacity(cpu))
+ upmigrate = sched_downmigrate;
+
+ if (boost_policy != SCHED_BOOST_ON_BIG) {
if (task_nice(p) > SCHED_UPMIGRATE_MIN_NICE ||
upmigrate_discouraged(p))
return 1;
- upmigrate = sched_upmigrate;
- if (cpu_capacity(task_cpu(p)) > cpu_capacity(cpu))
- upmigrate = sched_downmigrate;
-
if (task_load < upmigrate)
return 1;
+ } else {
+ if (task_sched_boost(p) || task_load >= upmigrate)
+ return 0;
+
+ return 1;
}
return 0;
}
-enum sched_boost_type sched_boost_type(void)
-{
- if (sched_boost())
- return sched_boost_policy;
-
- return SCHED_BOOST_NONE;
-}
-
int task_will_fit(struct task_struct *p, int cpu)
{
u64 tload = scale_load_to_cpu(task_load(p), cpu);
- return task_load_will_fit(p, tload, cpu, sched_boost_type());
+ return task_load_will_fit(p, tload, cpu, sched_boost_policy());
}
-int group_will_fit(struct sched_cluster *cluster,
- struct related_thread_group *grp, u64 demand)
+static int
+group_will_fit(struct sched_cluster *cluster, struct related_thread_group *grp,
+ u64 demand, bool group_boost)
{
int cpu = cluster_first_cpu(cluster);
int prev_capacity = 0;
- unsigned int threshold = sched_upmigrate;
+ unsigned int threshold = sched_group_upmigrate;
u64 load;
if (cluster->capacity == max_capacity)
return 1;
+ if (group_boost)
+ return 0;
+
+ if (!demand)
+ return 1;
+
if (grp->preferred_cluster)
prev_capacity = grp->preferred_cluster->capacity;
if (cluster->capacity < prev_capacity)
- threshold = sched_downmigrate;
+ threshold = sched_group_downmigrate;
load = scale_load_to_cpu(demand, cpu);
if (load < threshold)
@@ -1495,6 +1374,23 @@ void post_big_task_count_change(const struct cpumask *cpus)
DEFINE_MUTEX(policy_mutex);
+unsigned int update_freq_aggregate_threshold(unsigned int threshold)
+{
+ unsigned int old_threshold;
+
+ mutex_lock(&policy_mutex);
+
+ old_threshold = sysctl_sched_freq_aggregate_threshold_pct;
+
+ sysctl_sched_freq_aggregate_threshold_pct = threshold;
+ sched_freq_aggregate_threshold =
+ pct_to_real(sysctl_sched_freq_aggregate_threshold_pct);
+
+ mutex_unlock(&policy_mutex);
+
+ return old_threshold;
+}
+
static inline int invalid_value_freq_input(unsigned int *data)
{
if (data == &sysctl_sched_freq_aggregate)
@@ -1578,7 +1474,9 @@ int sched_hmp_proc_update_handler(struct ctl_table *table, int write,
if (write && (old_val == *data))
goto done;
- if (sysctl_sched_downmigrate_pct > sysctl_sched_upmigrate_pct) {
+ if (sysctl_sched_downmigrate_pct > sysctl_sched_upmigrate_pct ||
+ sysctl_sched_group_downmigrate_pct >
+ sysctl_sched_group_upmigrate_pct) {
*data = old_val;
ret = -EINVAL;
goto done;
@@ -3110,37 +3008,9 @@ static void reset_all_task_stats(void)
{
struct task_struct *g, *p;
- read_lock(&tasklist_lock);
do_each_thread(g, p) {
- raw_spin_lock_irq(&p->pi_lock);
reset_task_stats(p);
- raw_spin_unlock_irq(&p->pi_lock);
} while_each_thread(g, p);
- read_unlock(&tasklist_lock);
-}
-
-static void disable_window_stats(void)
-{
- unsigned long flags;
- int i;
-
- local_irq_save(flags);
- for_each_possible_cpu(i)
- raw_spin_lock(&cpu_rq(i)->lock);
-
- sched_disable_window_stats = 1;
-
- for_each_possible_cpu(i)
- raw_spin_unlock(&cpu_rq(i)->lock);
-
- local_irq_restore(flags);
-}
-
-/* Called with all cpu's rq->lock held */
-static void enable_window_stats(void)
-{
- sched_disable_window_stats = 0;
-
}
enum reset_reason_code {
@@ -3166,17 +3036,22 @@ void reset_all_window_stats(u64 window_start, unsigned int window_size)
unsigned int old = 0, new = 0;
struct related_thread_group *grp;
- read_lock(&related_thread_group_lock);
-
- disable_window_stats();
+ local_irq_save(flags);
- reset_all_task_stats();
+ read_lock(&tasklist_lock);
- local_irq_save(flags);
+ read_lock(&related_thread_group_lock);
+ /* Taking all runqueue locks prevents race with sched_exit(). */
for_each_possible_cpu(cpu)
raw_spin_lock(&cpu_rq(cpu)->lock);
+ sched_disable_window_stats = 1;
+
+ reset_all_task_stats();
+
+ read_unlock(&tasklist_lock);
+
list_for_each_entry(grp, &related_thread_groups, list) {
int j;
@@ -3196,7 +3071,7 @@ void reset_all_window_stats(u64 window_start, unsigned int window_size)
sched_load_granule = sched_ravg_window / NUM_LOAD_INDICES;
}
- enable_window_stats();
+ sched_disable_window_stats = 0;
for_each_possible_cpu(cpu) {
struct rq *rq = cpu_rq(cpu);
@@ -3239,10 +3114,10 @@ void reset_all_window_stats(u64 window_start, unsigned int window_size)
for_each_possible_cpu(cpu)
raw_spin_unlock(&cpu_rq(cpu)->lock);
- local_irq_restore(flags);
-
read_unlock(&related_thread_group_lock);
+ local_irq_restore(flags);
+
trace_sched_reset_all_window_stats(window_start, window_size,
sched_ktime_clock() - start_ts, reason, old, new);
}
@@ -3824,13 +3699,13 @@ static void check_for_up_down_migrate_update(const struct cpumask *cpus)
}
/* Return cluster which can offer required capacity for group */
-static struct sched_cluster *
-best_cluster(struct related_thread_group *grp, u64 total_demand)
+static struct sched_cluster *best_cluster(struct related_thread_group *grp,
+ u64 total_demand, bool group_boost)
{
struct sched_cluster *cluster = NULL;
for_each_sched_cluster(cluster) {
- if (group_will_fit(cluster, grp, total_demand))
+ if (group_will_fit(cluster, grp, total_demand, group_boost))
return cluster;
}
@@ -3841,6 +3716,9 @@ static void _set_preferred_cluster(struct related_thread_group *grp)
{
struct task_struct *p;
u64 combined_demand = 0;
+ bool boost_on_big = sched_boost_policy() == SCHED_BOOST_ON_BIG;
+ bool group_boost = false;
+ u64 wallclock;
if (!sysctl_sched_enable_colocation) {
grp->last_update = sched_ktime_clock();
@@ -3848,31 +3726,43 @@ static void _set_preferred_cluster(struct related_thread_group *grp)
return;
}
+ if (list_empty(&grp->tasks))
+ return;
+
+ wallclock = sched_ktime_clock();
+
/*
* wakeup of two or more related tasks could race with each other and
* could result in multiple calls to _set_preferred_cluster being issued
* at same time. Avoid overhead in such cases of rechecking preferred
* cluster
*/
- if (sched_ktime_clock() - grp->last_update < sched_ravg_window / 10)
+ if (wallclock - grp->last_update < sched_ravg_window / 10)
return;
- list_for_each_entry(p, &grp->tasks, grp_list)
+ list_for_each_entry(p, &grp->tasks, grp_list) {
+ if (boost_on_big && task_sched_boost(p)) {
+ group_boost = true;
+ break;
+ }
+
+ if (p->ravg.mark_start < wallclock -
+ (sched_ravg_window * sched_ravg_hist_size))
+ continue;
+
combined_demand += p->ravg.demand;
- grp->preferred_cluster = best_cluster(grp, combined_demand);
+ }
+
+ grp->preferred_cluster = best_cluster(grp,
+ combined_demand, group_boost);
grp->last_update = sched_ktime_clock();
trace_sched_set_preferred_cluster(grp, combined_demand);
}
void set_preferred_cluster(struct related_thread_group *grp)
{
- /*
- * Prevent possible deadlock with update_children(). Not updating
- * the preferred cluster once is not a big deal.
- */
- if (!raw_spin_trylock(&grp->lock))
- return;
+ raw_spin_lock(&grp->lock);
_set_preferred_cluster(grp);
raw_spin_unlock(&grp->lock);
}
@@ -3880,6 +3770,8 @@ void set_preferred_cluster(struct related_thread_group *grp)
#define ADD_TASK 0
#define REM_TASK 1
+#define DEFAULT_CGROUP_COLOC_ID 1
+
static inline void free_group_cputime(struct related_thread_group *grp)
{
free_percpu(grp->cpu_time);
@@ -4116,64 +4008,19 @@ static void free_related_thread_group(struct rcu_head *rcu)
kfree(grp);
}
-/*
- * The thread group for a task can change while we are here. However,
- * add_new_task_to_grp() will take care of any tasks that we miss here.
- * When a parent exits, and a child thread is simultaneously exiting,
- * sched_set_group_id() will synchronize those operations.
- */
-static void update_children(struct task_struct *leader,
- struct related_thread_group *grp, int event)
-{
- struct task_struct *child;
- struct rq *rq;
- unsigned long flags;
-
- if (!thread_group_leader(leader))
- return;
-
- if (event == ADD_TASK && !sysctl_sched_enable_thread_grouping)
- return;
-
- if (thread_group_empty(leader))
- return;
-
- child = next_thread(leader);
-
- do {
- rq = task_rq_lock(child, &flags);
-
- if (event == REM_TASK && child->grp && grp == child->grp) {
- transfer_busy_time(rq, grp, child, event);
- list_del_init(&child->grp_list);
- rcu_assign_pointer(child->grp, NULL);
- } else if (event == ADD_TASK && !child->grp) {
- transfer_busy_time(rq, grp, child, event);
- list_add(&child->grp_list, &grp->tasks);
- rcu_assign_pointer(child->grp, grp);
- }
-
- task_rq_unlock(rq, child, &flags);
- } while_each_thread(leader, child);
-
-}
-
static void remove_task_from_group(struct task_struct *p)
{
struct related_thread_group *grp = p->grp;
struct rq *rq;
int empty_group = 1;
- unsigned long flags;
raw_spin_lock(&grp->lock);
- rq = task_rq_lock(p, &flags);
+ rq = __task_rq_lock(p);
transfer_busy_time(rq, p->grp, p, REM_TASK);
list_del_init(&p->grp_list);
rcu_assign_pointer(p->grp, NULL);
- task_rq_unlock(rq, p, &flags);
-
- update_children(p, grp, REM_TASK);
+ __task_rq_unlock(rq);
if (!list_empty(&grp->tasks)) {
empty_group = 0;
@@ -4182,7 +4029,8 @@ static void remove_task_from_group(struct task_struct *p)
raw_spin_unlock(&grp->lock);
- if (empty_group) {
+ /* Reserved groups cannot be destroyed */
+ if (empty_group && grp->id != DEFAULT_CGROUP_COLOC_ID) {
list_del(&grp->list);
call_rcu(&grp->rcu, free_related_thread_group);
}
@@ -4192,7 +4040,6 @@ static int
add_task_to_group(struct task_struct *p, struct related_thread_group *grp)
{
struct rq *rq;
- unsigned long flags;
raw_spin_lock(&grp->lock);
@@ -4200,13 +4047,11 @@ add_task_to_group(struct task_struct *p, struct related_thread_group *grp)
* Change p->grp under rq->lock. Will prevent races with read-side
* reference of p->grp in various hot-paths
*/
- rq = task_rq_lock(p, &flags);
+ rq = __task_rq_lock(p);
transfer_busy_time(rq, grp, p, ADD_TASK);
list_add(&p->grp_list, &grp->tasks);
rcu_assign_pointer(p->grp, grp);
- task_rq_unlock(rq, p, &flags);
-
- update_children(p, grp, ADD_TASK);
+ __task_rq_unlock(rq);
_set_preferred_cluster(grp);
@@ -4219,23 +4064,33 @@ void add_new_task_to_grp(struct task_struct *new)
{
unsigned long flags;
struct related_thread_group *grp;
- struct task_struct *parent;
+ struct task_struct *leader = new->group_leader;
+ unsigned int leader_grp_id = sched_get_group_id(leader);
- if (!sysctl_sched_enable_thread_grouping)
+ if (!sysctl_sched_enable_thread_grouping &&
+ leader_grp_id != DEFAULT_CGROUP_COLOC_ID)
return;
if (thread_group_leader(new))
return;
- parent = new->group_leader;
+ if (leader_grp_id == DEFAULT_CGROUP_COLOC_ID) {
+ if (!same_schedtune(new, leader))
+ return;
+ }
write_lock_irqsave(&related_thread_group_lock, flags);
rcu_read_lock();
- grp = task_related_thread_group(parent);
+ grp = task_related_thread_group(leader);
rcu_read_unlock();
- /* Its possible that update_children() already added us to the group */
+ /*
+ * It's possible that someone already added the new task to the
+ * group. A leader's thread group is updated prior to calling
+ * this function. It's also possible that the leader has exited
+ * the group. In either case, there is nothing else to do.
+ */
if (!grp || new->grp) {
write_unlock_irqrestore(&related_thread_group_lock, flags);
return;
@@ -4250,14 +4105,55 @@ void add_new_task_to_grp(struct task_struct *new)
write_unlock_irqrestore(&related_thread_group_lock, flags);
}
+#if defined(CONFIG_SCHED_TUNE) && defined(CONFIG_CGROUP_SCHEDTUNE)
+/*
+ * We create a default colocation group at boot. There is no need to
+ * synchronize tasks between cgroups at creation time because the
+ * correct cgroup hierarchy is not available at boot. Therefore cgroup
+ * colocation is turned off by default even though the colocation group
+ * itself has been allocated. Furthermore this colocation group cannot
+ * be destroyted once it has been created. All of this has been as part
+ * of runtime optimizations.
+ *
+ * The job of synchronizing tasks to the colocation group is done when
+ * the colocation flag in the cgroup is turned on.
+ */
+static int __init create_default_coloc_group(void)
+{
+ struct related_thread_group *grp = NULL;
+ unsigned long flags;
+
+ grp = alloc_related_thread_group(DEFAULT_CGROUP_COLOC_ID);
+ if (IS_ERR(grp)) {
+ WARN_ON(1);
+ return -ENOMEM;
+ }
+
+ write_lock_irqsave(&related_thread_group_lock, flags);
+ list_add(&grp->list, &related_thread_groups);
+ write_unlock_irqrestore(&related_thread_group_lock, flags);
+
+ update_freq_aggregate_threshold(MAX_FREQ_AGGR_THRESH);
+ return 0;
+}
+late_initcall(create_default_coloc_group);
+
+int sync_cgroup_colocation(struct task_struct *p, bool insert)
+{
+ unsigned int grp_id = insert ? DEFAULT_CGROUP_COLOC_ID : 0;
+
+ return sched_set_group_id(p, grp_id);
+}
+#endif
+
int sched_set_group_id(struct task_struct *p, unsigned int group_id)
{
int rc = 0;
unsigned long flags;
struct related_thread_group *grp = NULL;
- /* Prevents tasks from exiting while we are managing groups. */
- write_lock_irqsave(&related_thread_group_lock, flags);
+ raw_spin_lock_irqsave(&p->pi_lock, flags);
+ write_lock(&related_thread_group_lock);
/* Switching from one group to another directly is not permitted */
if ((current != p && p->flags & PF_EXITING) ||
@@ -4272,6 +4168,12 @@ int sched_set_group_id(struct task_struct *p, unsigned int group_id)
grp = lookup_related_thread_group(group_id);
if (!grp) {
+ /* This is a reserved id */
+ if (group_id == DEFAULT_CGROUP_COLOC_ID) {
+ rc = -EINVAL;
+ goto done;
+ }
+
grp = alloc_related_thread_group(group_id);
if (IS_ERR(grp)) {
rc = -ENOMEM;
@@ -4281,10 +4183,10 @@ int sched_set_group_id(struct task_struct *p, unsigned int group_id)
list_add(&grp->list, &related_thread_groups);
}
- BUG_ON(!grp);
rc = add_task_to_group(p, grp);
done:
- write_unlock_irqrestore(&related_thread_group_lock, flags);
+ write_unlock(&related_thread_group_lock);
+ raw_spin_unlock_irqrestore(&p->pi_lock, flags);
return rc;
}
@@ -4529,7 +4431,7 @@ bool early_detection_notify(struct rq *rq, u64 wallclock)
struct task_struct *p;
int loop_max = 10;
- if (!sched_boost() || !rq->cfs.h_nr_running)
+ if (sched_boost_policy() == SCHED_BOOST_NONE || !rq->cfs.h_nr_running)
return 0;
rq->ed_task = NULL;
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index ba4403e910d8..12a04f30ef77 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1677,8 +1677,13 @@ static int find_lowest_rq_hmp(struct task_struct *task)
int prev_cpu = task_cpu(task);
u64 cpu_load, min_load = ULLONG_MAX;
int i;
- int restrict_cluster = sched_boost() ? 0 :
- sysctl_sched_restrict_cluster_spill;
+ int restrict_cluster;
+ int boost_on_big;
+
+ boost_on_big = sched_boost() == FULL_THROTTLE_BOOST &&
+ sched_boost_policy() == SCHED_BOOST_ON_BIG;
+
+ restrict_cluster = sysctl_sched_restrict_cluster_spill;
/* Make sure the mask is initialized first */
if (unlikely(!lowest_mask))
@@ -1697,6 +1702,9 @@ static int find_lowest_rq_hmp(struct task_struct *task)
*/
for_each_sched_cluster(cluster) {
+ if (boost_on_big && cluster->capacity != max_possible_capacity)
+ continue;
+
cpumask_and(&candidate_mask, &cluster->cpus, lowest_mask);
cpumask_andnot(&candidate_mask, &candidate_mask,
cpu_isolated_mask);
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 4289bf6cd642..30838bb9b442 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1061,8 +1061,6 @@ extern unsigned int max_load_scale_factor;
extern unsigned int max_possible_capacity;
extern unsigned int min_max_possible_capacity;
extern unsigned int max_power_cost;
-extern unsigned int sched_upmigrate;
-extern unsigned int sched_downmigrate;
extern unsigned int sched_init_task_load_windows;
extern unsigned int up_down_migrate_scale_factor;
extern unsigned int sysctl_sched_restrict_cluster_spill;
@@ -1106,18 +1104,23 @@ extern void sched_account_irqstart(int cpu, struct task_struct *curr,
u64 wallclock);
extern unsigned int cpu_temp(int cpu);
extern unsigned int nr_eligible_big_tasks(int cpu);
-extern void update_up_down_migrate(void);
extern int update_preferred_cluster(struct related_thread_group *grp,
struct task_struct *p, u32 old_load);
extern void set_preferred_cluster(struct related_thread_group *grp);
extern void add_new_task_to_grp(struct task_struct *new);
+extern unsigned int update_freq_aggregate_threshold(unsigned int threshold);
-enum sched_boost_type {
+enum sched_boost_policy {
SCHED_BOOST_NONE,
SCHED_BOOST_ON_BIG,
SCHED_BOOST_ON_ALL,
};
+#define NO_BOOST 0
+#define FULL_THROTTLE_BOOST 1
+#define CONSERVATIVE_BOOST 2
+#define RESTRAINED_BOOST 3
+
static inline struct sched_cluster *cpu_cluster(int cpu)
{
return cpu_rq(cpu)->cluster;
@@ -1387,14 +1390,11 @@ extern void set_hmp_defaults(void);
extern int power_delta_exceeded(unsigned int cpu_cost, unsigned int base_cost);
extern unsigned int power_cost(int cpu, u64 demand);
extern void reset_all_window_stats(u64 window_start, unsigned int window_size);
-extern void boost_kick(int cpu);
extern int sched_boost(void);
extern int task_load_will_fit(struct task_struct *p, u64 task_load, int cpu,
- enum sched_boost_type boost_type);
-extern enum sched_boost_type sched_boost_type(void);
+ enum sched_boost_policy boost_policy);
+extern enum sched_boost_policy sched_boost_policy(void);
extern int task_will_fit(struct task_struct *p, int cpu);
-extern int group_will_fit(struct sched_cluster *cluster,
- struct related_thread_group *grp, u64 demand);
extern u64 cpu_load(int cpu);
extern u64 cpu_load_sync(int cpu, int sync);
extern int preferred_cluster(struct sched_cluster *cluster,
@@ -1422,10 +1422,32 @@ extern u64 cpu_upmigrate_discourage_read_u64(struct cgroup_subsys_state *css,
struct cftype *cft);
extern int cpu_upmigrate_discourage_write_u64(struct cgroup_subsys_state *css,
struct cftype *cft, u64 upmigrate_discourage);
-extern void sched_hmp_parse_dt(void);
-extern void init_sched_hmp_boost_policy(void);
+extern void sched_boost_parse_dt(void);
extern void clear_top_tasks_bitmap(unsigned long *bitmap);
+#if defined(CONFIG_SCHED_TUNE) && defined(CONFIG_CGROUP_SCHEDTUNE)
+extern bool task_sched_boost(struct task_struct *p);
+extern int sync_cgroup_colocation(struct task_struct *p, bool insert);
+extern bool same_schedtune(struct task_struct *tsk1, struct task_struct *tsk2);
+extern void update_cgroup_boost_settings(void);
+extern void restore_cgroup_boost_settings(void);
+
+#else
+static inline bool
+same_schedtune(struct task_struct *tsk1, struct task_struct *tsk2)
+{
+ return true;
+}
+
+static inline bool task_sched_boost(struct task_struct *p)
+{
+ return true;
+}
+
+static inline void update_cgroup_boost_settings(void) { }
+static inline void restore_cgroup_boost_settings(void) { }
+#endif
+
#else /* CONFIG_SCHED_HMP */
struct hmp_sched_stats;
@@ -1615,8 +1637,7 @@ static inline void post_big_task_count_change(void) { }
static inline void set_hmp_defaults(void) { }
static inline void clear_reserved(int cpu) { }
-static inline void sched_hmp_parse_dt(void) {}
-static inline void init_sched_hmp_boost_policy(void) {}
+static inline void sched_boost_parse_dt(void) {}
#define trace_sched_cpu_load(...)
#define trace_sched_cpu_load_lb(...)
diff --git a/kernel/sched/tune.c b/kernel/sched/tune.c
index 4f8182302e5e..ee2af8e0b5ce 100644
--- a/kernel/sched/tune.c
+++ b/kernel/sched/tune.c
@@ -25,6 +25,33 @@ struct schedtune {
/* Boost value for tasks on that SchedTune CGroup */
int boost;
+#ifdef CONFIG_SCHED_HMP
+ /* Toggle ability to override sched boost enabled */
+ bool sched_boost_no_override;
+
+ /*
+ * Controls whether a cgroup is eligible for sched boost or not. This
+ * can temporariliy be disabled by the kernel based on the no_override
+ * flag above.
+ */
+ bool sched_boost_enabled;
+
+ /*
+ * This tracks the default value of sched_boost_enabled and is used
+ * restore the value following any temporary changes to that flag.
+ */
+ bool sched_boost_enabled_backup;
+
+ /*
+ * Controls whether tasks of this cgroup should be colocated with each
+ * other and tasks of other cgroups that have the same flag turned on.
+ */
+ bool colocate;
+
+ /* Controls whether further updates are allowed to the colocate flag */
+ bool colocate_update_disabled;
+#endif
+
};
static inline struct schedtune *css_st(struct cgroup_subsys_state *css)
@@ -54,6 +81,13 @@ static inline struct schedtune *parent_st(struct schedtune *st)
static struct schedtune
root_schedtune = {
.boost = 0,
+#ifdef CONFIG_SCHED_HMP
+ .sched_boost_no_override = false,
+ .sched_boost_enabled = true,
+ .sched_boost_enabled_backup = true,
+ .colocate = false,
+ .colocate_update_disabled = false,
+#endif
};
/*
@@ -97,6 +131,121 @@ struct boost_groups {
/* Boost groups affecting each CPU in the system */
DEFINE_PER_CPU(struct boost_groups, cpu_boost_groups);
+#ifdef CONFIG_SCHED_HMP
+static inline void init_sched_boost(struct schedtune *st)
+{
+ st->sched_boost_no_override = false;
+ st->sched_boost_enabled = true;
+ st->sched_boost_enabled_backup = st->sched_boost_enabled;
+ st->colocate = false;
+ st->colocate_update_disabled = false;
+}
+
+bool same_schedtune(struct task_struct *tsk1, struct task_struct *tsk2)
+{
+ return task_schedtune(tsk1) == task_schedtune(tsk2);
+}
+
+void update_cgroup_boost_settings(void)
+{
+ int i;
+
+ for (i = 0; i < BOOSTGROUPS_COUNT; i++) {
+ if (!allocated_group[i])
+ break;
+
+ if (allocated_group[i]->sched_boost_no_override)
+ continue;
+
+ allocated_group[i]->sched_boost_enabled = false;
+ }
+}
+
+void restore_cgroup_boost_settings(void)
+{
+ int i;
+
+ for (i = 0; i < BOOSTGROUPS_COUNT; i++) {
+ if (!allocated_group[i])
+ break;
+
+ allocated_group[i]->sched_boost_enabled =
+ allocated_group[i]->sched_boost_enabled_backup;
+ }
+}
+
+bool task_sched_boost(struct task_struct *p)
+{
+ struct schedtune *st = task_schedtune(p);
+
+ return st->sched_boost_enabled;
+}
+
+static u64
+sched_boost_override_read(struct cgroup_subsys_state *css,
+ struct cftype *cft)
+{
+ struct schedtune *st = css_st(css);
+
+ return st->sched_boost_no_override;
+}
+
+static int sched_boost_override_write(struct cgroup_subsys_state *css,
+ struct cftype *cft, u64 override)
+{
+ struct schedtune *st = css_st(css);
+
+ st->sched_boost_no_override = !!override;
+
+ return 0;
+}
+
+static u64 sched_boost_enabled_read(struct cgroup_subsys_state *css,
+ struct cftype *cft)
+{
+ struct schedtune *st = css_st(css);
+
+ return st->sched_boost_enabled;
+}
+
+static int sched_boost_enabled_write(struct cgroup_subsys_state *css,
+ struct cftype *cft, u64 enable)
+{
+ struct schedtune *st = css_st(css);
+
+ st->sched_boost_enabled = !!enable;
+ st->sched_boost_enabled_backup = st->sched_boost_enabled;
+
+ return 0;
+}
+
+static u64 sched_colocate_read(struct cgroup_subsys_state *css,
+ struct cftype *cft)
+{
+ struct schedtune *st = css_st(css);
+
+ return st->colocate;
+}
+
+static int sched_colocate_write(struct cgroup_subsys_state *css,
+ struct cftype *cft, u64 colocate)
+{
+ struct schedtune *st = css_st(css);
+
+ if (st->colocate_update_disabled)
+ return -EPERM;
+
+ st->colocate = !!colocate;
+ st->colocate_update_disabled = true;
+ return 0;
+}
+
+#else /* CONFIG_SCHED_HMP */
+
+static inline void init_sched_boost(struct schedtune *st) { }
+
+#endif /* CONFIG_SCHED_HMP */
+
static u64
boost_read(struct cgroup_subsys_state *css, struct cftype *cft)
{
@@ -121,12 +270,45 @@ boost_write(struct cgroup_subsys_state *css, struct cftype *cft,
return 0;
}
+static void schedtune_attach(struct cgroup_taskset *tset)
+{
+ struct task_struct *task;
+ struct cgroup_subsys_state *css;
+ struct schedtune *st;
+ bool colocate;
+
+ cgroup_taskset_first(tset, &css);
+ st = css_st(css);
+
+ colocate = st->colocate;
+
+ cgroup_taskset_for_each(task, css, tset)
+ sync_cgroup_colocation(task, colocate);
+}
+
static struct cftype files[] = {
{
.name = "boost",
.read_u64 = boost_read,
.write_u64 = boost_write,
},
+#ifdef CONFIG_SCHED_HMP
+ {
+ .name = "sched_boost_no_override",
+ .read_u64 = sched_boost_override_read,
+ .write_u64 = sched_boost_override_write,
+ },
+ {
+ .name = "sched_boost_enabled",
+ .read_u64 = sched_boost_enabled_read,
+ .write_u64 = sched_boost_enabled_write,
+ },
+ {
+ .name = "colocate",
+ .read_u64 = sched_colocate_read,
+ .write_u64 = sched_colocate_write,
+ },
+#endif
{ } /* terminate */
};
@@ -189,6 +371,7 @@ schedtune_css_alloc(struct cgroup_subsys_state *parent_css)
/* Initialize per CPUs boost group support */
st->idx = idx;
+ init_sched_boost(st);
if (schedtune_boostgroup_init(st))
goto release;
@@ -222,6 +405,7 @@ struct cgroup_subsys schedtune_cgrp_subsys = {
.legacy_cftypes = files,
.early_init = 1,
.allow_attach = subsys_cgroup_allow_attach,
+ .attach = schedtune_attach,
};
#endif /* CONFIG_CGROUP_SCHEDTUNE */
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 574316f1c344..b7cbd7940f7b 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -124,6 +124,7 @@ static int __maybe_unused neg_one = -1;
static int zero;
static int __maybe_unused one = 1;
static int __maybe_unused two = 2;
+static int __maybe_unused three = 3;
static int __maybe_unused four = 4;
static unsigned long one_ul = 1;
static int one_hundred = 100;
@@ -377,6 +378,22 @@ static struct ctl_table kern_table[] = {
.extra2 = &one_hundred,
},
{
+ .procname = "sched_group_upmigrate",
+ .data = &sysctl_sched_group_upmigrate_pct,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = sched_hmp_proc_update_handler,
+ .extra1 = &zero,
+ },
+ {
+ .procname = "sched_group_downmigrate",
+ .data = &sysctl_sched_group_downmigrate_pct,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = sched_hmp_proc_update_handler,
+ .extra1 = &zero,
+ },
+ {
.procname = "sched_init_task_load",
.data = &sysctl_sched_init_task_load_pct,
.maxlen = sizeof(unsigned int),
@@ -487,6 +504,8 @@ static struct ctl_table kern_table[] = {
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = sched_boost_handler,
+ .extra1 = &zero,
+ .extra2 = &three,
},
#endif /* CONFIG_SCHED_HMP */
#ifdef CONFIG_SCHED_DEBUG
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 18d2fe271cf7..c3914e8f87b0 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -49,6 +49,7 @@
#include <linux/sched/deadline.h>
#include <linux/timer.h>
#include <linux/freezer.h>
+#include <linux/delay.h>
#include <asm/uaccess.h>
@@ -1648,6 +1649,12 @@ static void migrate_hrtimer_list(struct hrtimer_cpu_base *old_base,
raw_spin_unlock(&old_base->lock);
raw_spin_unlock(&new_base->lock);
cpu_relax();
+ /*
+ * cpu_relax may just be a barrier. Grant the
+ * run_hrtimer_list code some time to obtain the
+ * spinlock.
+ */
+ udelay(2);
raw_spin_lock(&new_base->lock);
raw_spin_lock_nested(&old_base->lock,
SINGLE_DEPTH_NESTING);
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 748eefb72a91..5ebefc7cfa4f 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1640,7 +1640,7 @@ static void migrate_timer_list(struct tvec_base *new_base,
}
}
-static void __migrate_timers(int cpu, bool wait, bool remove_pinned)
+static void __migrate_timers(int cpu, bool remove_pinned)
{
struct tvec_base *old_base;
struct tvec_base *new_base;
@@ -1656,18 +1656,14 @@ static void __migrate_timers(int cpu, bool wait, bool remove_pinned)
spin_lock_irqsave(&new_base->lock, flags);
spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
- if (wait) {
- /* Ensure timers are done running before continuing */
- while (old_base->running_timer) {
- spin_unlock(&old_base->lock);
- spin_unlock_irqrestore(&new_base->lock, flags);
- cpu_relax();
- spin_lock_irqsave(&new_base->lock, flags);
- spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
- }
- } else {
+ /*
+ * If we're in the hotplug path, kill the system if there's a running
+ * timer. It's ok to have a running timer in the isolation case - the
+ * currently running or just expired timers are off of the timer wheel
+ * and so everything else can be migrated off.
+ */
+ if (!cpu_online(cpu))
BUG_ON(old_base->running_timer);
- }
for (i = 0; i < TVR_SIZE; i++)
migrate_timer_list(new_base, old_base->tv1.vec + i,
@@ -1692,12 +1688,12 @@ static void __migrate_timers(int cpu, bool wait, bool remove_pinned)
static void migrate_timers(int cpu)
{
BUG_ON(cpu_online(cpu));
- __migrate_timers(cpu, false, true);
+ __migrate_timers(cpu, true);
}
void timer_quiesce_cpu(void *cpup)
{
- __migrate_timers(*(int *)cpup, true, false);
+ __migrate_timers(*(int *)cpup, false);
}
static int timer_cpu_notify(struct notifier_block *self,
diff --git a/mm/debug-pagealloc.c b/mm/debug-pagealloc.c
index e060c7cdf24c..100963091cc6 100644
--- a/mm/debug-pagealloc.c
+++ b/mm/debug-pagealloc.c
@@ -113,6 +113,7 @@ static void check_poison_mem(struct page *page,
print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1, start,
end - start + 1, 1);
+ BUG_ON(PANIC_CORRUPTION);
dump_stack();
}
diff --git a/net/core/filter.c b/net/core/filter.c
index 75e9b2b2336d..eedb05468fcb 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -52,9 +52,10 @@
#include <net/dst.h>
/**
- * sk_filter - run a packet through a socket filter
+ * sk_filter_trim_cap - run a packet through a socket filter
* @sk: sock associated with &sk_buff
* @skb: buffer to filter
+ * @cap: limit on how short the eBPF program may trim the packet
*
* Run the eBPF program and then cut skb->data to correct size returned by
* the program. If pkt_len is 0 we toss packet. If skb->len is smaller
@@ -63,7 +64,7 @@
* be accepted or -EPERM if the packet should be tossed.
*
*/
-int sk_filter(struct sock *sk, struct sk_buff *skb)
+int sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb, unsigned int cap)
{
int err;
struct sk_filter *filter;
@@ -85,13 +86,13 @@ int sk_filter(struct sock *sk, struct sk_buff *skb)
if (filter) {
unsigned int pkt_len = bpf_prog_run_save_cb(filter->prog, skb);
- err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM;
+ err = pkt_len ? pskb_trim(skb, max(cap, pkt_len)) : -EPERM;
}
rcu_read_unlock();
return err;
}
-EXPORT_SYMBOL(sk_filter);
+EXPORT_SYMBOL(sk_filter_trim_cap);
static u64 __skb_get_pay_offset(u64 ctx, u64 a, u64 x, u64 r4, u64 r5)
{
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 07408b81bcd7..e3b0b55f2c92 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1529,6 +1529,21 @@ bool tcp_prequeue(struct sock *sk, struct sk_buff *skb)
}
EXPORT_SYMBOL(tcp_prequeue);
+int tcp_filter(struct sock *sk, struct sk_buff *skb)
+{
+ struct tcphdr *th = (struct tcphdr *)skb->data;
+ unsigned int eaten = skb->len;
+ int err;
+
+ err = sk_filter_trim_cap(sk, skb, th->doff * 4);
+ if (!err) {
+ eaten -= skb->len;
+ TCP_SKB_CB(skb)->end_seq -= eaten;
+ }
+ return err;
+}
+EXPORT_SYMBOL(tcp_filter);
+
/*
* From tcp_input.c
*/
@@ -1634,8 +1649,10 @@ process:
nf_reset(skb);
- if (sk_filter(sk, skb))
+ if (tcp_filter(sk, skb))
goto discard_and_relse;
+ th = (const struct tcphdr *)skb->data;
+ iph = ip_hdr(skb);
skb->dev = NULL;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 04955a5d2350..8647afa77db4 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1199,7 +1199,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
if (skb->protocol == htons(ETH_P_IP))
return tcp_v4_do_rcv(sk, skb);
- if (sk_filter(sk, skb))
+ if (tcp_filter(sk, skb))
goto discard;
/*
@@ -1431,8 +1431,10 @@ process:
if (tcp_v6_inbound_md5_hash(sk, skb))
goto discard_and_relse;
- if (sk_filter(sk, skb))
+ if (tcp_filter(sk, skb))
goto discard_and_relse;
+ th = (const struct tcphdr *)skb->data;
+ hdr = ipv6_hdr(skb);
skb->dev = NULL;
diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c
index dda332d821e4..456a1dff692d 100644
--- a/net/netfilter/xt_IDLETIMER.c
+++ b/net/netfilter/xt_IDLETIMER.c
@@ -460,9 +460,9 @@ static void idletimer_tg_destroy(const struct xt_tgdtor_param *par)
list_del(&info->timer->entry);
del_timer_sync(&info->timer->timer);
- cancel_work_sync(&info->timer->work);
sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr);
unregister_pm_notifier(&info->timer->pm_nb);
+ cancel_work_sync(&info->timer->work);
kfree(info->timer->attr.attr.name);
kfree(info->timer);
} else {
diff --git a/net/rmnet_data/rmnet_data_vnd.c b/net/rmnet_data/rmnet_data_vnd.c
index 4e3a205551e0..2999e2c15fdb 100644
--- a/net/rmnet_data/rmnet_data_vnd.c
+++ b/net/rmnet_data/rmnet_data_vnd.c
@@ -180,6 +180,7 @@ static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb,
rmnet_vnd_add_qos_header(skb,
dev,
dev_conf->qos_version);
+ skb_orphan(skb);
rmnet_egress_handler(skb, &dev_conf->local_ep);
} else {
dev->stats.tx_dropped++;
diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
index 79c4abcfa6b4..fb31d2ea5a81 100644
--- a/net/rose/rose_in.c
+++ b/net/rose/rose_in.c
@@ -164,7 +164,8 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety
rose_frames_acked(sk, nr);
if (ns == rose->vr) {
rose_start_idletimer(sk);
- if (sock_queue_rcv_skb(sk, skb) == 0) {
+ if (sk_filter_trim_cap(sk, skb, ROSE_MIN_LEN) == 0 &&
+ sock_queue_rcv_skb(sk, skb) == 0) {
rose->vr = (rose->vr + 1) % ROSE_MODULUS;
queued = 1;
} else {
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
index 23b7c76ff2d8..89130cf4db04 100644
--- a/net/wireless/db.txt
+++ b/net/wireless/db.txt
@@ -16,7 +16,7 @@ country 00:
(57240 - 63720 @ 2160), (0)
-country AE: DFS-FCC
+country AE: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (24), AUTO-BW
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
@@ -52,13 +52,12 @@ country AN: DFS-ETSI
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
(5490 - 5710 @ 160), (30), DFS
-country AR: DFS-FCC
- (2402 - 2482 @ 40), (20)
- (5170 - 5250 @ 80), (24), AUTO-BW
- (5250 - 5330 @ 80), (24), DFS, AUTO-BW
- (5490 - 5590 @ 80), (24), DFS
- (5650 - 5730 @ 80), (24), DFS
- (5735 - 5835 @ 80), (30)
+country AR:
+ (2402 - 2482 @ 40), (36)
+ (5170 - 5330 @ 160), (23)
+ (5490 - 5590 @ 80), (36)
+ (5650 - 5730 @ 80), (36)
+ (5735 - 5835 @ 80), (36)
country AS: DFS-FCC
(2402 - 2472 @ 40), (30)
@@ -162,11 +161,10 @@ country BG: DFS-ETSI
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
-country BH: DFS-ETSI
+country BH:
(2402 - 2482 @ 40), (20)
- (5170 - 5250 @ 20), (20)
- (5250 - 5330 @ 20), (20), DFS
- (5735 - 5835 @ 20), (20)
+ (5170 - 5330 @ 20), (23)
+ (5735 - 5835 @ 20), (33)
country BL: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -219,8 +217,10 @@ country BY: DFS-ETSI
(5490 - 5710 @ 160), (30), DFS
country BZ:
- (2402 - 2482 @ 40), (30)
- (5735 - 5835 @ 80), (30)
+ (2402 - 2482 @ 40), (36)
+ (5170 - 5330 @ 160), (27)
+ (5490 - 5730 @ 160), (36)
+ (5735 - 5835 @ 80), (36)
country CA: DFS-FCC
(2402 - 2472 @ 40), (30)
@@ -259,10 +259,9 @@ country CI: DFS-FCC
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-country CL: DFS-ETSI
+country CL:
(2402 - 2482 @ 40), (20)
- (5170 - 5250 @ 80), (20), AUTO-BW
- (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5170 - 5330 @ 160), (20)
(5735 - 5835 @ 80), (20)
country CN: DFS-FCC
@@ -416,9 +415,9 @@ country EE: DFS-ETSI
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
country EG: DFS-ETSI
- (2402 - 2482 @ 20), (20)
- (5170 - 5250 @ 20), (23)
- (5250 - 5330 @ 20), (23), DFS
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 40), (23)
+ (5250 - 5330 @ 40), (23), DFS
country ES: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -581,11 +580,10 @@ country HK: DFS-FCC
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-country HN: DFS-FCC
+country HN:
(2402 - 2482 @ 40), (20)
- (5170 - 5250 @ 80), (24), AUTO-BW
- (5250 - 5330 @ 80), (24), DFS, AUTO-BW
- (5490 - 5730 @ 160), (24), DFS
+ (5170 - 5330 @ 160), (24)
+ (5490 - 5730 @ 160), (24)
(5735 - 5835 @ 80), (30)
country HR: DFS-ETSI
@@ -657,10 +655,9 @@ country IL: DFS-ETSI
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
-country IN: DFS-ETSI
+country IN:
(2402 - 2482 @ 40), (20)
- (5170 - 5250 @ 80), (23), AUTO-BW
- (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5170 - 5330 @ 160), (23)
(5735 - 5835 @ 80), (30)
country IR:
@@ -735,7 +732,7 @@ country KH: DFS-ETSI
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
(5490 - 5710 @ 160), (30), DFS
-country KN: DFS-ETSI
+country KN: DFS-FCC
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
@@ -746,8 +743,8 @@ country KR: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (20), AUTO-BW
(5250 - 5330 @ 80), (20), DFS, AUTO-BW
- (5490 - 5630 @ 80), (30), DFS
- (5735 - 5815 @ 80), (30)
+ (5490 - 5710 @ 80), (30), DFS
+ (5735 - 5835 @ 80), (30)
# 60 GHz band channels 1-4,
# ref: http://www.law.go.kr/%ED%96%89%EC%A0%95%EA%B7%9C%EC%B9%99/%EB%AC%B4%EC%84%A0%EC%84%A4%EB%B9%84%EA%B7%9C%EC%B9%99
(57000 - 66000 @ 2160), (43)
@@ -781,7 +778,7 @@ country LB: DFS-FCC
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-country LC: DFS-ETSI
+country LC: DFS-FCC
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (20), AUTO-BW
(5250 - 5330 @ 80), (30), DFS, AUTO-BW
@@ -1047,10 +1044,9 @@ country NO: DFS-ETSI
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
-country NP: DFS-ETSI
+country NP:
(2402 - 2482 @ 40), (20)
- (5170 - 5250 @ 80), (20), AUTO-BW
- (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5170 - 5330 @ 160), (20)
(5735 - 5835 @ 80), (20)
country NZ: DFS-FCC
@@ -1066,11 +1062,11 @@ country OM: DFS-ETSI
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
(5490 - 5710 @ 160), (30), DFS
-country PA: DFS-FCC
+country PA:
(2402 - 2472 @ 40), (30)
- (5170 - 5250 @ 80), (23), AUTO-BW
- (5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5735 - 5835 @ 80), (30)
+ (5170 - 5250 @ 80), (23), AUT0-BW
+ (5250 - 5330 @ 80), (30), AUTO-BW
+ (5735 - 5835 @ 80), (36)
country PE: DFS-FCC
(2402 - 2482 @ 40), (20)
@@ -1208,11 +1204,10 @@ country RS: DFS-ETSI
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
-country RU: DFS-ETSI
+country RU:
(2402 - 2482 @ 40), (20)
- (5170 - 5250 @ 80), (23), AUTO-BW
- (5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5730 @ 160), (30), DFS
+ (5170 - 5330 @ 160), (23)
+ (5490 - 5730 @ 160), (30)
(5735 - 5835 @ 80), (30)
country RW: DFS-FCC
@@ -1286,11 +1281,10 @@ country SK: DFS-ETSI
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
-country SN: DFS-FCC
+country SN:
(2402 - 2482 @ 40), (20)
- (5170 - 5250 @ 80), (24), AUTO-BW
- (5250 - 5330 @ 80), (24), DFS, AUTO-BW
- (5490 - 5730 @ 160), (24), DFS
+ (5170 - 5330 @ 160), (24)
+ (5490 - 5730 @ 160), (24)
(5735 - 5835 @ 80), (30)
country SR: DFS-ETSI
@@ -1347,12 +1341,11 @@ country TR: DFS-ETSI
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
-country TT: DFS-FCC
+country TT:
(2402 - 2482 @ 40), (20)
- (5170 - 5250 @ 80), (24), AUTO-BW
- (5250 - 5330 @ 80), (24), DFS, AUTO-BW
- (5490 - 5730 @ 160), (24), DFS
- (5735 - 5835 @ 80), (30)
+ (5170 - 5330 @ 160), (27)
+ (5490 - 5730 @ 160), (36)
+ (5735 - 5835 @ 80), (36)
country TW: DFS-FCC
(2402 - 2472 @ 40), (30)
diff --git a/sound/soc/codecs/msm8x16/msm8x16-wcd.c b/sound/soc/codecs/msm8x16/msm8x16-wcd.c
index 481e1efdf015..c73414681c5a 100644
--- a/sound/soc/codecs/msm8x16/msm8x16-wcd.c
+++ b/sound/soc/codecs/msm8x16/msm8x16-wcd.c
@@ -40,9 +40,10 @@
#include <sound/tlv.h>
#include <sound/q6core.h>
#include <soc/qcom/subsystem_notif.h>
-#include "msm8x16-wcd.h"
+#include "../../msm/msmfalcon-common.h"
#include "../wcd-mbhc-v2.h"
#include "msm8916-wcd-irq.h"
+#include "msm8x16-wcd.h"
#define DRV_NAME "msm-codec"
#define MSM89XX_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
@@ -253,8 +254,6 @@ static struct wcd_mbhc_register
WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE",
MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT,
0x10, 4, 0),
- WCD_MBHC_REGISTER("WCD_MBHC_MOISTURE_VREF",
- 0, 0, 0, 0),
WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL",
MSM89XX_PMIC_ANALOG_MICB_2_EN, 0x20, 5, 0),
WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN",
@@ -295,7 +294,7 @@ static int msm8x16_wcd_dt_parse_vreg_info(struct device *dev,
const char *vreg_name, bool ondemand);
static struct msm8x16_wcd_pdata *msm8x16_wcd_populate_dt_pdata(
struct device *dev);
-static int msm8x16_wcd_enable_ext_mb_source(struct snd_soc_codec *codec,
+static int msm8x16_wcd_enable_ext_mb_source(struct wcd_mbhc *mbhc,
bool turn_on);
static void msm8x16_trim_btn_reg(struct snd_soc_codec *codec);
static void msm8x16_wcd_set_micb_v(struct snd_soc_codec *codec);
@@ -335,35 +334,28 @@ static int get_codec_version(struct msm8x16_wcd_priv *msm8x16_wcd)
static int msm_digcdc_clock_control(bool flag)
{
int ret = -EINVAL;
- struct msm8916_asoc_mach_data *pdata = NULL;
+ struct msm_asoc_mach_data *pdata = NULL;
pdata = snd_soc_card_get_drvdata(registered_codec->component.card);
if (flag) {
- mutex_lock(&pdata->cdc_mclk_mutex);
- if (atomic_read(&pdata->mclk_enabled) == false) {
- if (pdata->afe_clk_ver == AFE_CLK_VERSION_V1) {
- pdata->digital_cdc_clk.clk_val =
- pdata->mclk_freq;
- ret = afe_set_digital_codec_core_clock(
- AFE_PORT_ID_PRIMARY_MI2S_RX,
- &pdata->digital_cdc_clk);
- } else {
- pdata->digital_cdc_core_clk.enable = 1;
- ret = afe_set_lpass_clock_v2(
- AFE_PORT_ID_PRIMARY_MI2S_RX,
- &pdata->digital_cdc_core_clk);
- }
+ mutex_lock(&pdata->cdc_int_mclk0_mutex);
+ if (atomic_read(&pdata->int_mclk0_enabled) == false) {
+ pdata->digital_cdc_core_clk.enable = 1;
+ ret = afe_set_lpass_clock_v2(
+ AFE_PORT_ID_INT0_MI2S_RX,
+ &pdata->digital_cdc_core_clk);
if (ret < 0) {
- pr_err("failed to enable the MCLK\n");
- goto err;
+ pr_err("failed to enable the INT_MCLK0\n");
+ goto err_mclk;
}
pr_err("enabled digital codec core clk\n");
- atomic_set(&pdata->mclk_enabled, true);
- schedule_delayed_work(&pdata->disable_mclk_work, 50);
+ atomic_set(&pdata->int_mclk0_enabled, true);
+ schedule_delayed_work(&pdata->disable_int_mclk0_work,
+ 50);
}
-err:
- mutex_unlock(&pdata->cdc_mclk_mutex);
+err_mclk:
+ mutex_unlock(&pdata->cdc_int_mclk0_mutex);
return ret;
}
return 0;
@@ -617,11 +609,12 @@ static void msm8x16_wcd_compute_impedance(struct snd_soc_codec *codec, s16 l,
}
static struct firmware_cal *msm8x16_wcd_get_hwdep_fw_cal(
- struct snd_soc_codec *codec,
+ struct wcd_mbhc *mbhc,
enum wcd_cal_type type)
{
struct msm8x16_wcd_priv *msm8x16_wcd;
struct firmware_cal *hwdep_cal;
+ struct snd_soc_codec *codec = mbhc->codec;
if (!codec) {
pr_err("%s: NULL codec pointer\n", __func__);
@@ -1063,10 +1056,11 @@ exit:
pr_err("%s: Impedance detection completed\n", __func__);
}
-static int msm8x16_register_notifier(struct snd_soc_codec *codec,
+static int msm8x16_register_notifier(struct wcd_mbhc *mbhc,
struct notifier_block *nblock,
bool enable)
{
+ struct snd_soc_codec *codec = mbhc->codec;
struct msm8x16_wcd_priv *msm8x16_wcd =
snd_soc_codec_get_drvdata(codec);
@@ -1624,7 +1618,7 @@ out:
static int msm8x16_wcd_codec_enable_clock_block(struct snd_soc_codec *codec,
int enable)
{
- struct msm8916_asoc_mach_data *pdata = NULL;
+ struct msm_asoc_mach_data *pdata = NULL;
pdata = snd_soc_card_get_drvdata(codec->component.card);
if (enable) {
@@ -1776,7 +1770,7 @@ static int msm8x16_wcd_loopback_mode_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
- struct msm8916_asoc_mach_data *pdata = NULL;
+ struct msm_asoc_mach_data *pdata = NULL;
pdata = snd_soc_card_get_drvdata(codec->component.card);
dev_err(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
@@ -1789,7 +1783,7 @@ static int msm8x16_wcd_loopback_mode_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
- struct msm8916_asoc_mach_data *pdata = NULL;
+ struct msm_asoc_mach_data *pdata = NULL;
pdata = snd_soc_card_get_drvdata(codec->component.card);
dev_err(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
@@ -3061,7 +3055,7 @@ static int msm8x16_wcd_codec_enable_dig_clk(struct snd_soc_dapm_widget *w,
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);
- struct msm8916_asoc_mach_data *pdata = NULL;
+ struct msm_asoc_mach_data *pdata = NULL;
pdata = snd_soc_card_get_drvdata(codec->component.card);
@@ -3202,11 +3196,12 @@ static void msm8x16_trim_btn_reg(struct snd_soc_codec *codec)
pr_err("%s: This device is trimmed at ATE\n", __func__);
}
}
-static int msm8x16_wcd_enable_ext_mb_source(struct snd_soc_codec *codec,
+static int msm8x16_wcd_enable_ext_mb_source(struct wcd_mbhc *mbhc,
bool turn_on)
{
int ret = 0;
static int count;
+ struct snd_soc_codec *codec = mbhc->codec;
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
dev_err(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on,
@@ -3405,7 +3400,7 @@ static int msm8x16_wcd_codec_enable_dec(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
- struct msm8916_asoc_mach_data *pdata = NULL;
+ struct msm_asoc_mach_data *pdata = NULL;
unsigned int decimator;
struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);
char *dec_name = NULL;
@@ -4328,14 +4323,14 @@ int msm8x16_wcd_mclk_enable(struct snd_soc_codec *codec,
dev_err(codec->dev, "%s: mclk_enable = %u, dapm = %d\n",
__func__, mclk_enable, dapm);
if (mclk_enable) {
- msm8x16_wcd->mclk_enabled = true;
+ msm8x16_wcd->int_mclk0_enabled = true;
msm8x16_wcd_codec_enable_clock_block(codec, 1);
} else {
- if (!msm8x16_wcd->mclk_enabled) {
+ if (!msm8x16_wcd->int_mclk0_enabled) {
dev_err(codec->dev, "Error, MCLK already diabled\n");
return -EINVAL;
}
- msm8x16_wcd->mclk_enabled = false;
+ msm8x16_wcd->int_mclk0_enabled = false;
msm8x16_wcd_codec_enable_clock_block(codec, 0);
}
return 0;
@@ -5178,7 +5173,7 @@ static struct regulator *wcd8x16_wcd_codec_find_regulator(
static int msm8x16_wcd_device_down(struct snd_soc_codec *codec)
{
- struct msm8916_asoc_mach_data *pdata = NULL;
+ struct msm_asoc_mach_data *pdata = NULL;
struct msm8x16_wcd_priv *msm8x16_wcd_priv =
snd_soc_codec_get_drvdata(codec);
int i;
@@ -5250,7 +5245,7 @@ static int msm8x16_wcd_device_down(struct snd_soc_codec *codec)
MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x93);
msm8x16_wcd_bringup(codec);
- atomic_set(&pdata->mclk_enabled, false);
+ atomic_set(&pdata->int_mclk0_enabled, false);
set_bit(BUS_DOWN, &msm8x16_wcd_priv->status_mask);
snd_soc_card_change_online_state(codec->component.card, 0);
return 0;
@@ -5399,7 +5394,7 @@ static void msm8x16_wcd_configure_cap(struct snd_soc_codec *codec,
bool micbias1, bool micbias2)
{
- struct msm8916_asoc_mach_data *pdata = NULL;
+ struct msm_asoc_mach_data *pdata = NULL;
pdata = snd_soc_card_get_drvdata(codec->component.card);
@@ -5553,7 +5548,7 @@ static int msm8x16_wcd_codec_probe(struct snd_soc_codec *codec)
wcd_mbhc_init(&msm8x16_wcd_priv->mbhc, codec, &mbhc_cb, &intr_ids,
wcd_mbhc_registers, true);
- msm8x16_wcd_priv->mclk_enabled = false;
+ msm8x16_wcd_priv->int_mclk0_enabled = false;
msm8x16_wcd_priv->clock_active = false;
msm8x16_wcd_priv->config_mode_active = false;
@@ -5654,33 +5649,23 @@ static int msm8x16_wcd_disable_static_supplies_to_optimum(
int msm8x16_wcd_suspend(struct snd_soc_codec *codec)
{
- struct msm8916_asoc_mach_data *pdata = NULL;
+ struct msm_asoc_mach_data *pdata = NULL;
struct msm8x16_wcd *msm8x16 = codec->control_data;
struct msm8x16_wcd_pdata *msm8x16_pdata = msm8x16->dev->platform_data;
pdata = snd_soc_card_get_drvdata(codec->component.card);
pr_err("%s: mclk cnt = %d, mclk_enabled = %d\n",
- __func__, atomic_read(&pdata->mclk_rsc_ref),
- atomic_read(&pdata->mclk_enabled));
- if (atomic_read(&pdata->mclk_enabled) == true) {
+ __func__, atomic_read(&pdata->int_mclk0_rsc_ref),
+ atomic_read(&pdata->int_mclk0_enabled));
+ if (atomic_read(&pdata->int_mclk0_enabled) == true) {
cancel_delayed_work_sync(
- &pdata->disable_mclk_work);
- mutex_lock(&pdata->cdc_mclk_mutex);
- if (atomic_read(&pdata->mclk_enabled) == true) {
- if (pdata->afe_clk_ver == AFE_CLK_VERSION_V1) {
- pdata->digital_cdc_clk.clk_val = 0;
- afe_set_digital_codec_core_clock(
- AFE_PORT_ID_PRIMARY_MI2S_RX,
- &pdata->digital_cdc_clk);
- } else {
- pdata->digital_cdc_core_clk.enable = 0;
- afe_set_lpass_clock_v2(
- AFE_PORT_ID_PRIMARY_MI2S_RX,
- &pdata->digital_cdc_core_clk);
- }
- atomic_set(&pdata->mclk_enabled, false);
- }
- mutex_unlock(&pdata->cdc_mclk_mutex);
+ &pdata->disable_int_mclk0_work);
+ mutex_lock(&pdata->cdc_int_mclk0_mutex);
+ pdata->digital_cdc_core_clk.enable = 0;
+ afe_set_lpass_clock_v2(AFE_PORT_ID_INT0_MI2S_RX,
+ &pdata->digital_cdc_core_clk);
+ atomic_set(&pdata->int_mclk0_enabled, false);
+ mutex_unlock(&pdata->cdc_int_mclk0_mutex);
}
msm8x16_wcd_disable_static_supplies_to_optimum(msm8x16, msm8x16_pdata);
return 0;
@@ -5688,7 +5673,7 @@ int msm8x16_wcd_suspend(struct snd_soc_codec *codec)
int msm8x16_wcd_resume(struct snd_soc_codec *codec)
{
- struct msm8916_asoc_mach_data *pdata = NULL;
+ struct msm_asoc_mach_data *pdata = NULL;
struct msm8x16_wcd *msm8x16 = codec->control_data;
struct msm8x16_wcd_pdata *msm8x16_pdata = msm8x16->dev->platform_data;
diff --git a/sound/soc/codecs/msm8x16/msm8x16-wcd.h b/sound/soc/codecs/msm8x16/msm8x16-wcd.h
index d2e782b07cb2..776090258119 100644
--- a/sound/soc/codecs/msm8x16/msm8x16-wcd.h
+++ b/sound/soc/codecs/msm8x16/msm8x16-wcd.h
@@ -221,31 +221,6 @@ struct wcd_imped_i_ref {
int offset;
};
-struct msm8916_asoc_mach_data {
- int codec_type;
- int ext_pa;
- int us_euro_gpio;
- int spk_ext_pa_gpio;
- int mclk_freq;
- int lb_mode;
- int afe_clk_ver;
- u8 micbias1_cap_mode;
- u8 micbias2_cap_mode;
- atomic_t mclk_rsc_ref;
- atomic_t mclk_enabled;
- atomic_t wsa_mclk_rsc_ref;
- struct mutex cdc_mclk_mutex;
- struct mutex wsa_mclk_mutex;
- struct delayed_work disable_mclk_work;
- struct afe_digital_clk_cfg digital_cdc_clk;
- struct afe_clk_set digital_cdc_core_clk;
- void __iomem *vaddr_gpio_mux_spkr_ctl;
- void __iomem *vaddr_gpio_mux_mic_ctl;
- void __iomem *vaddr_gpio_mux_quin_ctl;
- void __iomem *vaddr_gpio_mux_pcm_ctl;
- struct on_demand_supply wsa_switch_supply;
-};
-
struct msm8x16_wcd_pdata {
int irq;
int irq_base;
@@ -291,7 +266,7 @@ struct msm8x16_wcd_priv {
u32 rx_bias_count;
s32 dmic_1_2_clk_cnt;
u32 mute_mask;
- bool mclk_enabled;
+ bool int_mclk0_enabled;
bool clock_active;
bool config_mode_active;
u16 boost_option;
diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c
index a1f23685beb5..debb6c5e52d5 100644
--- a/sound/soc/codecs/wcd-mbhc-v2.c
+++ b/sound/soc/codecs/wcd-mbhc-v2.c
@@ -902,6 +902,11 @@ static int wcd_check_cross_conn(struct wcd_mbhc *mbhc)
return -EINVAL;
}
+ /* If PA is enabled, dont check for cross-connection */
+ if (mbhc->mbhc_cb->hph_pa_on_status)
+ if (mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec))
+ return false;
+
WCD_MBHC_REG_READ(WCD_MBHC_ELECT_SCHMT_ISRC, reg1);
/*
* Check if there is any cross connection,
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
index 393b8b4b8084..06e00fdfe6a1 100644
--- a/sound/soc/codecs/wcd9335.c
+++ b/sound/soc/codecs/wcd9335.c
@@ -11820,7 +11820,7 @@ static struct snd_soc_dai_driver tasha_dai[] = {
.capture = {
.stream_name = "AIF1 Capture",
.rates = WCD9335_RATES_MASK,
- .formats = TASHA_FORMATS,
+ .formats = TASHA_FORMATS_S16_S24_LE,
.rate_max = 192000,
.rate_min = 8000,
.channels_min = 1,
@@ -11848,7 +11848,7 @@ static struct snd_soc_dai_driver tasha_dai[] = {
.capture = {
.stream_name = "AIF2 Capture",
.rates = WCD9335_RATES_MASK,
- .formats = TASHA_FORMATS,
+ .formats = TASHA_FORMATS_S16_S24_LE,
.rate_max = 192000,
.rate_min = 8000,
.channels_min = 1,
@@ -11876,7 +11876,7 @@ static struct snd_soc_dai_driver tasha_dai[] = {
.capture = {
.stream_name = "AIF3 Capture",
.rates = WCD9335_RATES_MASK,
- .formats = TASHA_FORMATS,
+ .formats = TASHA_FORMATS_S16_S24_LE,
.rate_max = 48000,
.rate_min = 8000,
.channels_min = 1,
@@ -11977,7 +11977,7 @@ static struct snd_soc_dai_driver tasha_i2s_dai[] = {
.capture = {
.stream_name = "AIF1 Capture",
.rates = WCD9335_RATES_MASK,
- .formats = TASHA_FORMATS,
+ .formats = TASHA_FORMATS_S16_S24_LE,
.rate_max = 192000,
.rate_min = 8000,
.channels_min = 1,
@@ -12005,7 +12005,7 @@ static struct snd_soc_dai_driver tasha_i2s_dai[] = {
.capture = {
.stream_name = "AIF2 Capture",
.rates = WCD9335_RATES_MASK,
- .formats = TASHA_FORMATS,
+ .formats = TASHA_FORMATS_S16_S24_LE,
.rate_max = 192000,
.rate_min = 8000,
.channels_min = 1,
diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c
index d989ae3bed6c..56882be12554 100644
--- a/sound/soc/codecs/wcd934x/wcd934x.c
+++ b/sound/soc/codecs/wcd934x/wcd934x.c
@@ -8598,21 +8598,6 @@ done:
return rc;
}
-static void tavil_enable_sido_buck(struct snd_soc_codec *codec)
-{
- struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
-
- snd_soc_update_bits(codec, WCD934X_ANA_RCO, 0x80, 0x80);
- usleep_range(100, 110);
- snd_soc_update_bits(codec, WCD934X_ANA_BUCK_CTL, 0x02, 0x02);
- usleep_range(100, 110);
- snd_soc_update_bits(codec, WCD934X_ANA_BUCK_CTL, 0x01, 0x01);
- usleep_range(100, 110);
- snd_soc_update_bits(codec, WCD934X_ANA_BUCK_CTL, 0x04, 0x04);
- usleep_range(100, 110);
- tavil->resmgr->sido_input_src = SIDO_SOURCE_RCO_BG;
-}
-
static void tavil_cdc_vote_svs(struct snd_soc_codec *codec, bool vote)
{
struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
@@ -8715,7 +8700,8 @@ static int tavil_device_down(struct wcd9xxx *wcd9xxx)
for (count = 0; count < NUM_CODEC_DAIS; count++)
priv->dai[count].bus_down_in_recovery = true;
wcd_dsp_ssr_event(priv->wdsp_cntl, WCD_CDC_DOWN_EVENT);
- priv->resmgr->sido_input_src = SIDO_SOURCE_INTERNAL;
+ wcd_resmgr_set_sido_input_src_locked(priv->resmgr,
+ SIDO_SOURCE_INTERNAL);
return 0;
}
@@ -8887,7 +8873,6 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec)
tavil->comp_enabled[i] = 0;
tavil_codec_init_reg(tavil);
- tavil_enable_sido_buck(codec);
pdata = dev_get_platdata(codec->dev->parent);
ret = tavil_handle_pdata(tavil, pdata);
@@ -9462,7 +9447,6 @@ err_mem:
static int __tavil_enable_efuse_sensing(struct tavil_priv *tavil)
{
int val, rc;
- struct snd_soc_codec *codec;
__tavil_cdc_mclk_enable(tavil, true);
@@ -9482,14 +9466,6 @@ static int __tavil_enable_efuse_sensing(struct tavil_priv *tavil)
WARN(1, "%s: Efuse sense is not complete val=%x, ret=%d\n",
__func__, val, rc);
- codec = tavil->codec;
- if (!codec) {
- pr_debug("%s: codec is not yet registered\n", __func__);
- goto done;
- }
- tavil_enable_sido_buck(codec);
-
-done:
__tavil_cdc_mclk_enable(tavil, false);
return rc;
diff --git a/sound/soc/codecs/wcd9xxx-resmgr-v2.c b/sound/soc/codecs/wcd9xxx-resmgr-v2.c
index 39ca965e791e..84754b8d09b0 100644
--- a/sound/soc/codecs/wcd9xxx-resmgr-v2.c
+++ b/sound/soc/codecs/wcd9xxx-resmgr-v2.c
@@ -25,6 +25,8 @@
#define WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL 0x0d41
#define WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL 0x0d42
+static void wcd_resmgr_set_sido_input_src(struct wcd9xxx_resmgr_v2 *resmgr,
+ int sido_src);
static const char *wcd_resmgr_clk_type_to_str(enum wcd_clock_type clk_type)
{
if (clk_type == WCD_CLK_OFF)
@@ -262,6 +264,8 @@ static int wcd_resmgr_enable_clk_mclk(struct wcd9xxx_resmgr_v2 *resmgr)
0x01, 0x01);
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD934X_CODEC_RPM_CLK_GATE, 0x03, 0x00);
+ wcd_resmgr_set_sido_input_src(resmgr,
+ SIDO_SOURCE_RCO_BG);
} else {
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
@@ -315,6 +319,10 @@ static int wcd_resmgr_disable_clk_mclk(struct wcd9xxx_resmgr_v2 *resmgr)
0x80, 0x00);
}
+ if ((resmgr->codec_type == WCD934X) &&
+ (resmgr->clk_type == WCD_CLK_OFF))
+ wcd_resmgr_set_sido_input_src(resmgr, SIDO_SOURCE_INTERNAL);
+
pr_debug("%s: mclk_users: %d, clk_type: %s\n", __func__,
resmgr->clk_mclk_users,
wcd_resmgr_clk_type_to_str(resmgr->clk_type));
@@ -444,6 +452,9 @@ static int wcd_resmgr_disable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr)
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD9335_ANA_RCO,
0x80, 0x00);
+ wcd_resmgr_codec_reg_update_bits(resmgr,
+ WCD934X_CLK_SYS_MCLK_PRG,
+ 0x01, 0x00);
resmgr->clk_type = WCD_CLK_OFF;
} else if ((resmgr->clk_rco_users == 0) &&
(resmgr->clk_mclk_users)) {
@@ -455,6 +466,11 @@ static int wcd_resmgr_disable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr)
WCD9335_ANA_RCO,
0x80, 0x00);
}
+
+ if ((resmgr->codec_type == WCD934X) &&
+ (resmgr->clk_type == WCD_CLK_OFF))
+ wcd_resmgr_set_sido_input_src(resmgr, SIDO_SOURCE_INTERNAL);
+
pr_debug("%s: rco clk users: %d, clk_type: %s\n", __func__,
resmgr->clk_rco_users,
wcd_resmgr_clk_type_to_str(resmgr->clk_type));
@@ -493,6 +509,64 @@ int wcd_resmgr_enable_clk_block(struct wcd9xxx_resmgr_v2 *resmgr,
return ret;
}
+static void wcd_resmgr_set_sido_input_src(struct wcd9xxx_resmgr_v2 *resmgr,
+ int sido_src)
+{
+ if (!resmgr)
+ return;
+
+ if (sido_src == resmgr->sido_input_src)
+ return;
+
+ if (sido_src == SIDO_SOURCE_INTERNAL) {
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
+ 0x04, 0x00);
+ usleep_range(100, 110);
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
+ 0x03, 0x00);
+ usleep_range(100, 110);
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_RCO,
+ 0x80, 0x00);
+ usleep_range(100, 110);
+ resmgr->sido_input_src = SIDO_SOURCE_INTERNAL;
+ pr_debug("%s: sido input src to internal\n", __func__);
+ } else if (sido_src == SIDO_SOURCE_RCO_BG) {
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_RCO,
+ 0x80, 0x80);
+ usleep_range(100, 110);
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
+ 0x02, 0x02);
+ usleep_range(100, 110);
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
+ 0x01, 0x01);
+ usleep_range(100, 110);
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
+ 0x04, 0x04);
+ usleep_range(100, 110);
+ resmgr->sido_input_src = SIDO_SOURCE_RCO_BG;
+ pr_debug("%s: sido input src to external\n", __func__);
+ }
+}
+
+/*
+ * wcd_resmgr_set_sido_input_src_locked:
+ * Set SIDO input in BG_CLK locked context
+ *
+ * @resmgr: handle to struct wcd9xxx_resmgr_v2
+ * @sido_src: Select the SIDO input source
+ */
+void wcd_resmgr_set_sido_input_src_locked(struct wcd9xxx_resmgr_v2 *resmgr,
+ int sido_src)
+{
+ if (!resmgr)
+ return;
+
+ WCD9XXX_V2_BG_CLK_LOCK(resmgr);
+ wcd_resmgr_set_sido_input_src(resmgr, sido_src);
+ WCD9XXX_V2_BG_CLK_UNLOCK(resmgr);
+}
+EXPORT_SYMBOL(wcd_resmgr_set_sido_input_src_locked);
+
/*
* wcd_resmgr_disable_clk_block: disable MCLK or RCO
* @resmgr: handle to struct wcd9xxx_resmgr_v2
diff --git a/sound/soc/codecs/wcd9xxx-resmgr-v2.h b/sound/soc/codecs/wcd9xxx-resmgr-v2.h
index c1955d31889f..f605a249a620 100644
--- a/sound/soc/codecs/wcd9xxx-resmgr-v2.h
+++ b/sound/soc/codecs/wcd9xxx-resmgr-v2.h
@@ -85,4 +85,6 @@ int wcd_resmgr_disable_clk_block(struct wcd9xxx_resmgr_v2 *resmgr,
enum wcd_clock_type type);
int wcd_resmgr_get_clk_type(struct wcd9xxx_resmgr_v2 *resmgr);
void wcd_resmgr_post_ssr_v2(struct wcd9xxx_resmgr_v2 *resmgr);
+void wcd_resmgr_set_sido_input_src_locked(struct wcd9xxx_resmgr_v2 *resmgr,
+ int sido_src);
#endif
diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig
index 64a1fa76604d..9cf69eca0028 100644
--- a/sound/soc/msm/Kconfig
+++ b/sound/soc/msm/Kconfig
@@ -98,6 +98,70 @@ config SND_SOC_CPE
The configuration includes the cpe lsm driver to enable
listen on codec.
+config SND_SOC_INT_CODEC
+ tristate "SoC Machine driver for MSMFALCON_INT"
+ depends on ARCH_QCOM
+ select SND_SOC_QDSP6V2
+ select SND_SOC_MSM_STUB
+ select SND_SOC_MSM_HOSTLESS_PCM
+ select SND_DYNAMIC_MINORS
+ select MSM_QDSP6_APRV2_GLINK
+ select MSM_QDSP6_SSR
+ select MSM_QDSP6_PDR
+ select MSM_QDSP6_NOTIFIER
+ select MSM_QDSP6V2_CODECS
+ select SND_SOC_MSM_SWR
+ select SND_SOC_MSM8X16_WCD
+ select QTI_PP
+ select DTS_SRS_TM
+ select DOLBY_DAP
+ select DOLBY_DS2
+ select SND_HWDEP
+ select MSM_ULTRASOUND
+ select DTS_EAGLE
+ select SND_SOC_MSMFALCON_COMMON
+ select SND_SOC_COMPRESS
+ help
+ To add support for SoC audio on MSM_INT.
+ This will enable sound soc drivers which
+ interfaces with DSP, also it will enable
+ the machine driver and the corresponding
+ DAI-links
+
+config SND_SOC_EXT_CODEC
+ tristate "SoC Machine driver for MSMFALCON_EXT"
+ depends on ARCH_QCOM
+ select SND_SOC_QDSP6V2
+ select SND_SOC_MSM_STUB
+ select SND_SOC_MSM_HOSTLESS_PCM
+ select SND_DYNAMIC_MINORS
+ select MSM_QDSP6_APRV2_GLINK
+ select MSM_QDSP6_SSR
+ select MSM_QDSP6_PDR
+ select MSM_QDSP6_NOTIFIER
+ select MSM_QDSP6V2_CODECS
+ select SND_SOC_WCD9335
+ select SND_SOC_WCD934X
+ select SND_SOC_WSA881X
+ select MFD_CORE
+ select QTI_PP
+ select DTS_SRS_TM
+ select DOLBY_DAP
+ select DOLBY_DS2
+ select SND_SOC_CPE
+ select SND_SOC_WCD_CPE
+ select SND_HWDEP
+ select MSM_ULTRASOUND
+ select DTS_EAGLE
+ select SND_SOC_MSMFALCON_COMMON
+ select SND_SOC_COMPRESS
+ help
+ To add support for SoC audio on MSM_EXT.
+ This will enable sound soc drivers which
+ interfaces with DSP, also it will enable
+ the machine driver and the corresponding
+ DAI-links
+
config SND_SOC_MSM8996
tristate "SoC Machine driver for MSM8996 boards"
depends on ARCH_MSM8996
@@ -157,4 +221,16 @@ config SND_SOC_MSMCOBALT
the machine driver and the corresponding
DAI-links
+config SND_SOC_FALCON
+ tristate "SoC Machine driver for MSMFALCON boards"
+ depends on ARCH_MSMFALCON
+ select SND_SOC_INT_CODEC
+ select SND_SOC_EXT_CODEC
+ help
+ To add support for SoC audio on MSMFALCON.
+ This will enable sound soc drivers which
+ interfaces with DSP, also it will enable
+ the machine driver and the corresponding
+ DAI-links
+
endmenu
diff --git a/sound/soc/msm/Makefile b/sound/soc/msm/Makefile
index 3ad34be41578..799c9ee63d43 100644
--- a/sound/soc/msm/Makefile
+++ b/sound/soc/msm/Makefile
@@ -19,3 +19,18 @@ obj-$(CONFIG_SND_SOC_MSM8996) += snd-soc-msm8996.o
# for MSMCOBALT sound card driver
snd-soc-msmcobalt-objs := msmcobalt.o
obj-$(CONFIG_SND_SOC_MSMCOBALT) += snd-soc-msmcobalt.o
+
+# for MSMFALCON sound card driver
+snd-soc-msmfalcon-common-objs := msm-audio-pinctrl.o msmfalcon-common.o
+obj-$(CONFIG_SND_SOC_MSMFALCON_COMMON) += snd-soc-msmfalcon-common.o
+
+# for MSMFALCON sound card driver
+snd-soc-int-codec-objs := msmfalcon-internal.o
+obj-$(CONFIG_SND_SOC_INT_CODEC) += snd-soc-msmfalcon-common.o
+obj-$(CONFIG_SND_SOC_INT_CODEC) += snd-soc-int-codec.o
+
+# for MSMFALCON sound card driver
+snd-soc-ext-codec-objs := msmfalcon-external.o msmfalcon-ext-dai-links.o
+obj-$(CONFIG_SND_SOC_EXT_CODEC) += snd-soc-msmfalcon-common.o
+obj-$(CONFIG_SND_SOC_EXT_CODEC) += snd-soc-ext-codec.o
+
diff --git a/sound/soc/msm/msm-audio-pinctrl.h b/sound/soc/msm/msm-audio-pinctrl.h
index 0b5395520b1b..73eeaff39bfd 100644
--- a/sound/soc/msm/msm-audio-pinctrl.h
+++ b/sound/soc/msm/msm-audio-pinctrl.h
@@ -1,4 +1,4 @@
- /* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ /* Copyright (c) 2015-2016, 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
@@ -14,8 +14,7 @@
#define __MSM_AUDIO_PINCTRL_H
enum pinctrl_client {
- CLIENT_WCD_INT,
- CLIENT_WCD_EXT,
+ CLIENT_WCD,
CLIENT_WSA_BONGO_1,
CLIENT_WSA_BONGO_2,
MAX_PINCTRL_CLIENT,
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index ee9dcacdd5c9..aa036d352f40 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -870,6 +870,38 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.name = "QUAT_MI2S_RX_HOSTLESS",
.probe = fe_dai_probe,
},
+ {
+ .playback = {
+ .stream_name = "INT0 MI2S_RX Hostless Playback",
+ .aif_name = "INT0_MI2S_DL_HL",
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_fe_dai_ops,
+ .name = "INT0_MI2S_RX_HOSTLESS",
+ .probe = fe_dai_probe,
+ },
+ {
+ .playback = {
+ .stream_name = "INT4 MI2S_RX Hostless Playback",
+ .aif_name = "INT4_MI2S_DL_HL",
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_fe_dai_ops,
+ .name = "INT4_MI2S_RX_HOSTLESS",
+ .probe = fe_dai_probe,
+ },
/* TDM Hostless */
{
.capture = {
diff --git a/sound/soc/msm/msmcobalt.c b/sound/soc/msm/msmcobalt.c
index c295c26a6fd7..9c392f3d4ddc 100644
--- a/sound/soc/msm/msmcobalt.c
+++ b/sound/soc/msm/msmcobalt.c
@@ -3258,20 +3258,23 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_dapm_ignore_suspend(dapm, "EAR");
snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1");
snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2");
- snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3");
- snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4");
snd_soc_dapm_ignore_suspend(dapm, "ANC EAR");
snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT");
snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT");
snd_soc_dapm_ignore_suspend(dapm, "HPHL");
snd_soc_dapm_ignore_suspend(dapm, "HPHR");
- 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");
snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI");
snd_soc_dapm_ignore_suspend(dapm, "VIINPUT");
+ 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");
+ }
+
snd_soc_dapm_sync(dapm);
snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
diff --git a/sound/soc/msm/msmfalcon-common.c b/sound/soc/msm/msmfalcon-common.c
new file mode 100644
index 000000000000..c82319539f39
--- /dev/null
+++ b/sound/soc/msm/msmfalcon-common.c
@@ -0,0 +1,2806 @@
+/* Copyright (c) 2015-2016, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/input.h>
+#include <linux/of_gpio.h>
+#include <linux/mfd/msm-cdc-pinctrl.h>
+#include <sound/pcm_params.h>
+#include <sound/q6afe-v2.h>
+#include "qdsp6v2/msm-pcm-routing-v2.h"
+#include "msm-audio-pinctrl.h"
+#include "msmfalcon-common.h"
+#include "msmfalcon-internal.h"
+#include "msmfalcon-external.h"
+#include "../codecs/msm8x16/msm8x16-wcd.h"
+#include "../codecs/wsa881x.h"
+
+#define DRV_NAME "msmfalcon-asoc-snd"
+
+#define DEV_NAME_STR_LEN 32
+#define DEFAULT_MCLK_RATE 9600000
+
+struct dev_config {
+ u32 sample_rate;
+ u32 bit_format;
+ u32 channels;
+};
+
+/* TDM default config */
+static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
+ { /* PRI TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
+ },
+ { /* SEC TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
+ },
+ { /* TERT TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
+ },
+ { /* QUAT TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
+ }
+};
+
+/* TDM default config */
+static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
+ { /* PRI TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
+ },
+ { /* SEC TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
+ },
+ { /* TERT TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
+ },
+ { /* QUAT TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
+ }
+};
+
+static struct dev_config usb_rx_cfg = {
+ .sample_rate = SAMPLING_RATE_48KHZ,
+ .bit_format = SNDRV_PCM_FORMAT_S16_LE,
+ .channels = 2,
+};
+
+static struct dev_config usb_tx_cfg = {
+ .sample_rate = SAMPLING_RATE_48KHZ,
+ .bit_format = SNDRV_PCM_FORMAT_S16_LE,
+ .channels = 1,
+};
+
+enum {
+ PRIM_MI2S = 0,
+ SEC_MI2S,
+ TERT_MI2S,
+ QUAT_MI2S,
+ MI2S_MAX,
+};
+
+enum {
+ PRIM_AUX_PCM = 0,
+ SEC_AUX_PCM,
+ TERT_AUX_PCM,
+ QUAT_AUX_PCM,
+ AUX_PCM_MAX,
+};
+
+enum {
+ PCM_I2S_SEL_PRIM = 0,
+ PCM_I2S_SEL_SEC,
+ PCM_I2S_SEL_TERT,
+ PCM_I2S_SEL_QUAT,
+ PCM_I2S_SEL_MAX,
+};
+
+struct mi2s_aux_pcm_common_conf {
+ struct mutex lock;
+ void *pcm_i2s_sel_vt_addr;
+};
+
+struct mi2s_conf {
+ struct mutex lock;
+ u32 ref_cnt;
+ u32 msm_is_mi2s_master;
+};
+
+struct auxpcm_conf {
+ struct mutex lock;
+ u32 ref_cnt;
+};
+
+struct msm_wsa881x_dev_info {
+ struct device_node *of_node;
+ u32 index;
+};
+static struct snd_soc_aux_dev *msm_aux_dev;
+static struct snd_soc_codec_conf *msm_codec_conf;
+
+static bool msm_swap_gnd_mic(struct snd_soc_codec *codec);
+
+static struct wcd_mbhc_config mbhc_cfg = {
+ .read_fw_bin = false,
+ .calibration = NULL,
+ .detect_extn_cable = true,
+ .mono_stero_detection = false,
+ .swap_gnd_mic = NULL,
+ .hs_ext_micbias = false,
+ .key_code[0] = KEY_MEDIA,
+ .key_code[1] = KEY_VOICECOMMAND,
+ .key_code[2] = KEY_VOLUMEUP,
+ .key_code[3] = KEY_VOLUMEDOWN,
+ .key_code[4] = 0,
+ .key_code[5] = 0,
+ .key_code[6] = 0,
+ .key_code[7] = 0,
+ .linein_th = 5000,
+ .moisture_en = false,
+ .mbhc_micbias = 0,
+ .anc_micbias = 0,
+ .enable_anc_mic_detect = false,
+};
+
+static struct dev_config proxy_rx_cfg = {
+ .sample_rate = SAMPLING_RATE_48KHZ,
+ .bit_format = SNDRV_PCM_FORMAT_S16_LE,
+ .channels = 2,
+};
+
+/* Default configuration of MI2S channels */
+static struct dev_config mi2s_rx_cfg[] = {
+ [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+ [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+ [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+ [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+};
+
+static struct dev_config mi2s_tx_cfg[] = {
+ [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+};
+
+static struct dev_config aux_pcm_rx_cfg[] = {
+ [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+};
+
+static struct dev_config aux_pcm_tx_cfg[] = {
+ [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+};
+
+static char const *ch_text[] = {"Two", "Three", "Four", "Five",
+ "Six", "Seven", "Eight"};
+static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"};
+static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16",
+ "KHZ_32", "KHZ_44P1", "KHZ_48",
+ "KHZ_96", "KHZ_192"};
+static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four",
+ "Five", "Six", "Seven",
+ "Eight"};
+static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
+ "S32_LE"};
+static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four",
+ "Five", "Six", "Seven", "Eight"};
+static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"};
+static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32",
+ "KHZ_44P1", "KHZ_48", "KHZ_96",
+ "KHZ_192", "KHZ_352P8", "KHZ_384"};
+static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four",
+ "Five", "Six", "Seven",
+ "Eight"};
+static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025",
+ "KHZ_16", "KHZ_22P05",
+ "KHZ_32", "KHZ_44P1", "KHZ_48",
+ "KHZ_96", "KHZ_192", "KHZ_384"};
+
+static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text);
+
+static struct afe_clk_set mi2s_clk[MI2S_MAX] = {
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ },
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ },
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ },
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ }
+};
+
+static struct mi2s_aux_pcm_common_conf mi2s_auxpcm_conf[PCM_I2S_SEL_MAX];
+static struct mi2s_conf mi2s_intf_conf[MI2S_MAX];
+static struct auxpcm_conf auxpcm_intf_conf[AUX_PCM_MAX];
+
+static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: proxy_rx channels = %d\n",
+ __func__, proxy_rx_cfg.channels);
+ ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2;
+
+ return 0;
+}
+
+static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2;
+ pr_debug("%s: proxy_rx channels = %d\n",
+ __func__, proxy_rx_cfg.channels);
+
+ return 1;
+}
+
+static int tdm_get_sample_rate(int value)
+{
+ int sample_rate = 0;
+
+ switch (value) {
+ case 0:
+ sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ case 1:
+ sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 2:
+ sample_rate = SAMPLING_RATE_32KHZ;
+ break;
+ case 3:
+ sample_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 4:
+ sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 5:
+ sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 6:
+ sample_rate = SAMPLING_RATE_192KHZ;
+ break;
+ case 7:
+ sample_rate = SAMPLING_RATE_352P8KHZ;
+ break;
+ case 8:
+ sample_rate = SAMPLING_RATE_384KHZ;
+ break;
+ default:
+ sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+ return sample_rate;
+}
+
+static int tdm_get_sample_rate_val(int sample_rate)
+{
+ int sample_rate_val = 0;
+
+ switch (sample_rate) {
+ case SAMPLING_RATE_8KHZ:
+ sample_rate_val = 0;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ sample_rate_val = 1;
+ break;
+ case SAMPLING_RATE_32KHZ:
+ sample_rate_val = 2;
+ break;
+ case SAMPLING_RATE_44P1KHZ:
+ sample_rate_val = 3;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ sample_rate_val = 4;
+ break;
+ case SAMPLING_RATE_96KHZ:
+ sample_rate_val = 5;
+ break;
+ case SAMPLING_RATE_192KHZ:
+ sample_rate_val = 6;
+ break;
+ case SAMPLING_RATE_352P8KHZ:
+ sample_rate_val = 7;
+ break;
+ case SAMPLING_RATE_384KHZ:
+ sample_rate_val = 8;
+ break;
+ default:
+ sample_rate_val = 4;
+ break;
+ }
+ return sample_rate_val;
+}
+
+static int tdm_get_port_idx(struct snd_kcontrol *kcontrol,
+ struct tdm_port *port)
+{
+ if (port) {
+ if (strnstr(kcontrol->id.name, "PRI",
+ sizeof(kcontrol->id.name))) {
+ port->mode = TDM_PRI;
+ } else if (strnstr(kcontrol->id.name, "SEC",
+ sizeof(kcontrol->id.name))) {
+ port->mode = TDM_SEC;
+ } else if (strnstr(kcontrol->id.name, "TERT",
+ sizeof(kcontrol->id.name))) {
+ port->mode = TDM_TERT;
+ } else if (strnstr(kcontrol->id.name, "QUAT",
+ sizeof(kcontrol->id.name))) {
+ port->mode = TDM_QUAT;
+ } else {
+ pr_err("%s: unsupported mode in: %s",
+ __func__, kcontrol->id.name);
+ return -EINVAL;
+ }
+
+ if (strnstr(kcontrol->id.name, "RX_0",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_0",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_0;
+ } else if (strnstr(kcontrol->id.name, "RX_1",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_1",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_1;
+ } else if (strnstr(kcontrol->id.name, "RX_2",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_2",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_2;
+ } else if (strnstr(kcontrol->id.name, "RX_3",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_3",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_3;
+ } else if (strnstr(kcontrol->id.name, "RX_4",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_4",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_4;
+ } else if (strnstr(kcontrol->id.name, "RX_5",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_5",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_5;
+ } else if (strnstr(kcontrol->id.name, "RX_6",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_6",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_6;
+ } else if (strnstr(kcontrol->id.name, "RX_7",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_7",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_7;
+ } else {
+ pr_err("%s: unsupported channel in: %s",
+ __func__, kcontrol->id.name);
+ return -EINVAL;
+ }
+ } else
+ return -EINVAL;
+ return 0;
+}
+
+static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val(
+ tdm_rx_cfg[port.mode][port.channel].sample_rate);
+
+ pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__,
+ tdm_rx_cfg[port.mode][port.channel].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ tdm_rx_cfg[port.mode][port.channel].sample_rate =
+ tdm_get_sample_rate(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__,
+ tdm_rx_cfg[port.mode][port.channel].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val(
+ tdm_tx_cfg[port.mode][port.channel].sample_rate);
+
+ pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__,
+ tdm_tx_cfg[port.mode][port.channel].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ tdm_tx_cfg[port.mode][port.channel].sample_rate =
+ tdm_get_sample_rate(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__,
+ tdm_tx_cfg[port.mode][port.channel].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_get_format(int value)
+{
+ int format = 0;
+
+ switch (value) {
+ case 0:
+ format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ case 1:
+ format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 2:
+ format = SNDRV_PCM_FORMAT_S32_LE;
+ break;
+ default:
+ format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ return format;
+}
+
+static int tdm_get_format_val(int format)
+{
+ int value = 0;
+
+ switch (format) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ value = 0;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ value = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ value = 2;
+ break;
+ default:
+ value = 0;
+ break;
+ }
+ return value;
+}
+
+static int tdm_rx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ ucontrol->value.enumerated.item[0] = tdm_get_format_val(
+ tdm_rx_cfg[port.mode][port.channel].bit_format);
+
+ pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__,
+ tdm_rx_cfg[port.mode][port.channel].bit_format,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_rx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ tdm_rx_cfg[port.mode][port.channel].bit_format =
+ tdm_get_format(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__,
+ tdm_rx_cfg[port.mode][port.channel].bit_format,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_tx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ ucontrol->value.enumerated.item[0] = tdm_get_format_val(
+ tdm_tx_cfg[port.mode][port.channel].bit_format);
+
+ pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__,
+ tdm_tx_cfg[port.mode][port.channel].bit_format,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_tx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ tdm_tx_cfg[port.mode][port.channel].bit_format =
+ tdm_get_format(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__,
+ tdm_tx_cfg[port.mode][port.channel].bit_format,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+
+ ucontrol->value.enumerated.item[0] =
+ tdm_rx_cfg[port.mode][port.channel].channels - 1;
+
+ pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__,
+ tdm_rx_cfg[port.mode][port.channel].channels - 1,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ tdm_rx_cfg[port.mode][port.channel].channels =
+ ucontrol->value.enumerated.item[0] + 1;
+
+ pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__,
+ tdm_rx_cfg[port.mode][port.channel].channels,
+ ucontrol->value.enumerated.item[0] + 1);
+ }
+ return ret;
+}
+
+static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ ucontrol->value.enumerated.item[0] =
+ tdm_tx_cfg[port.mode][port.channel].channels - 1;
+
+ pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__,
+ tdm_tx_cfg[port.mode][port.channel].channels - 1,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ tdm_tx_cfg[port.mode][port.channel].channels =
+ ucontrol->value.enumerated.item[0] + 1;
+
+ pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__,
+ tdm_tx_cfg[port.mode][port.channel].channels,
+ ucontrol->value.enumerated.item[0] + 1);
+ }
+ return ret;
+}
+
+static int aux_pcm_get_sample_rate(int value)
+{
+ int sample_rate;
+
+ switch (value) {
+ case 1:
+ sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 0:
+ default:
+ sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ }
+ return sample_rate;
+}
+
+static int aux_pcm_get_sample_rate_val(int sample_rate)
+{
+ int sample_rate_val;
+
+ switch (sample_rate) {
+ case SAMPLING_RATE_16KHZ:
+ sample_rate_val = 1;
+ break;
+ case SAMPLING_RATE_8KHZ:
+ default:
+ sample_rate_val = 0;
+ break;
+ }
+ return sample_rate_val;
+}
+
+static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol)
+{
+ int idx;
+
+ if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM",
+ sizeof("PRIM_AUX_PCM")))
+ idx = PRIM_AUX_PCM;
+ else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM",
+ sizeof("SEC_AUX_PCM")))
+ idx = SEC_AUX_PCM;
+ else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM",
+ sizeof("TERT_AUX_PCM")))
+ idx = TERT_AUX_PCM;
+ else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM",
+ sizeof("QUAT_AUX_PCM")))
+ idx = QUAT_AUX_PCM;
+ else {
+ pr_err("%s: unsupported port: %s",
+ __func__, kcontrol->id.name);
+ idx = -EINVAL;
+ }
+
+ return idx;
+}
+
+static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ aux_pcm_rx_cfg[idx].sample_rate =
+ aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
+ idx, aux_pcm_rx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.enumerated.item[0] =
+ aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate);
+
+ pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
+ idx, aux_pcm_rx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ aux_pcm_tx_cfg[idx].sample_rate =
+ aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
+ idx, aux_pcm_tx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.enumerated.item[0] =
+ aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate);
+
+ pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
+ idx, aux_pcm_tx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol)
+{
+ int idx;
+
+ if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX",
+ sizeof("PRIM_MI2S_RX")))
+ idx = PRIM_MI2S;
+ else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX",
+ sizeof("SEC_MI2S_RX")))
+ idx = SEC_MI2S;
+ else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX",
+ sizeof("TERT_MI2S_RX")))
+ idx = TERT_MI2S;
+ else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX",
+ sizeof("QUAT_MI2S_RX")))
+ idx = QUAT_MI2S;
+ else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX",
+ sizeof("PRIM_MI2S_TX")))
+ idx = PRIM_MI2S;
+ else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX",
+ sizeof("SEC_MI2S_TX")))
+ idx = SEC_MI2S;
+ else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX",
+ sizeof("TERT_MI2S_TX")))
+ idx = TERT_MI2S;
+ else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX",
+ sizeof("QUAT_MI2S_TX")))
+ idx = QUAT_MI2S;
+ else {
+ pr_err("%s: unsupported channel: %s",
+ __func__, kcontrol->id.name);
+ idx = -EINVAL;
+ }
+
+ return idx;
+}
+
+static int mi2s_get_sample_rate_val(int sample_rate)
+{
+ int sample_rate_val;
+
+ switch (sample_rate) {
+ case SAMPLING_RATE_8KHZ:
+ sample_rate_val = 0;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ sample_rate_val = 1;
+ break;
+ case SAMPLING_RATE_32KHZ:
+ sample_rate_val = 2;
+ break;
+ case SAMPLING_RATE_44P1KHZ:
+ sample_rate_val = 3;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ sample_rate_val = 4;
+ break;
+ case SAMPLING_RATE_96KHZ:
+ sample_rate_val = 5;
+ break;
+ case SAMPLING_RATE_192KHZ:
+ sample_rate_val = 6;
+ break;
+ default:
+ sample_rate_val = 4;
+ break;
+ }
+ return sample_rate_val;
+}
+
+static int mi2s_get_sample_rate(int value)
+{
+ int sample_rate;
+
+ switch (value) {
+ case 0:
+ sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ case 1:
+ sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 2:
+ sample_rate = SAMPLING_RATE_32KHZ;
+ break;
+ case 3:
+ sample_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 4:
+ sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 5:
+ sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 6:
+ sample_rate = SAMPLING_RATE_192KHZ;
+ break;
+ default:
+ sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+ return sample_rate;
+}
+
+static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ mi2s_rx_cfg[idx].sample_rate =
+ mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
+ idx, mi2s_rx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.enumerated.item[0] =
+ mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate);
+
+ pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
+ idx, mi2s_rx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ mi2s_tx_cfg[idx].sample_rate =
+ mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
+ idx, mi2s_tx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.enumerated.item[0] =
+ mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate);
+
+ pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
+ idx, mi2s_tx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__,
+ idx, mi2s_rx_cfg[idx].channels);
+ ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1;
+
+ return 0;
+}
+
+static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1;
+ pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__,
+ idx, mi2s_rx_cfg[idx].channels);
+
+ return 1;
+}
+
+static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__,
+ idx, mi2s_tx_cfg[idx].channels);
+ ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1;
+
+ return 0;
+}
+
+static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1;
+ pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__,
+ idx, mi2s_tx_cfg[idx].channels);
+
+ return 1;
+}
+
+static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: usb_audio_rx_ch = %d\n", __func__,
+ usb_rx_cfg.channels);
+ ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1;
+ return 0;
+}
+
+static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1;
+
+ pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels);
+ return 1;
+}
+
+static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int sample_rate_val;
+
+ switch (usb_rx_cfg.sample_rate) {
+ case SAMPLING_RATE_384KHZ:
+ sample_rate_val = 9;
+ break;
+ case SAMPLING_RATE_192KHZ:
+ sample_rate_val = 8;
+ break;
+ case SAMPLING_RATE_96KHZ:
+ sample_rate_val = 7;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ sample_rate_val = 6;
+ break;
+ case SAMPLING_RATE_44P1KHZ:
+ sample_rate_val = 5;
+ break;
+ case SAMPLING_RATE_32KHZ:
+ sample_rate_val = 4;
+ break;
+ case SAMPLING_RATE_22P05KHZ:
+ sample_rate_val = 3;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ sample_rate_val = 2;
+ break;
+ case SAMPLING_RATE_11P025KHZ:
+ sample_rate_val = 1;
+ break;
+ case SAMPLING_RATE_8KHZ:
+ default:
+ sample_rate_val = 0;
+ break;
+ }
+
+ ucontrol->value.integer.value[0] = sample_rate_val;
+ pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__,
+ usb_rx_cfg.sample_rate);
+ return 0;
+}
+
+static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 9:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ;
+ break;
+ case 8:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ;
+ break;
+ case 7:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 6:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 5:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 4:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ;
+ break;
+ case 3:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ;
+ break;
+ case 2:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 1:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ;
+ break;
+ case 0:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ default:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+
+ pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n",
+ __func__, ucontrol->value.integer.value[0],
+ usb_rx_cfg.sample_rate);
+ return 0;
+}
+
+static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (usb_rx_cfg.bit_format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ ucontrol->value.integer.value[0] = 3;
+ break;
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+
+ pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n",
+ __func__, usb_rx_cfg.bit_format,
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int rc = 0;
+
+ switch (ucontrol->value.integer.value[0]) {
+ case 3:
+ usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE;
+ break;
+ case 2:
+ usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE;
+ break;
+ case 1:
+ usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n",
+ __func__, usb_rx_cfg.bit_format,
+ ucontrol->value.integer.value[0]);
+
+ return rc;
+}
+
+static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: usb_audio_tx_ch = %d\n", __func__,
+ usb_tx_cfg.channels);
+ ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1;
+ return 0;
+}
+
+static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1;
+
+ pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels);
+ return 1;
+}
+
+static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int sample_rate_val;
+
+ switch (usb_tx_cfg.sample_rate) {
+ case SAMPLING_RATE_384KHZ:
+ sample_rate_val = 9;
+ break;
+ case SAMPLING_RATE_192KHZ:
+ sample_rate_val = 8;
+ break;
+ case SAMPLING_RATE_96KHZ:
+ sample_rate_val = 7;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ sample_rate_val = 6;
+ break;
+ case SAMPLING_RATE_44P1KHZ:
+ sample_rate_val = 5;
+ break;
+ case SAMPLING_RATE_32KHZ:
+ sample_rate_val = 4;
+ break;
+ case SAMPLING_RATE_22P05KHZ:
+ sample_rate_val = 3;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ sample_rate_val = 2;
+ break;
+ case SAMPLING_RATE_11P025KHZ:
+ sample_rate_val = 1;
+ break;
+ case SAMPLING_RATE_8KHZ:
+ sample_rate_val = 0;
+ break;
+ default:
+ sample_rate_val = 6;
+ break;
+ }
+
+ ucontrol->value.integer.value[0] = sample_rate_val;
+ pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__,
+ usb_tx_cfg.sample_rate);
+ return 0;
+}
+
+static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 9:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ;
+ break;
+ case 8:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ;
+ break;
+ case 7:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 6:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 5:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 4:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ;
+ break;
+ case 3:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ;
+ break;
+ case 2:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 1:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ;
+ break;
+ case 0:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ default:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+
+ pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n",
+ __func__, ucontrol->value.integer.value[0],
+ usb_tx_cfg.sample_rate);
+ return 0;
+}
+
+static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (usb_tx_cfg.bit_format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ ucontrol->value.integer.value[0] = 3;
+ break;
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+
+ pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n",
+ __func__, usb_tx_cfg.bit_format,
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int rc = 0;
+
+ switch (ucontrol->value.integer.value[0]) {
+ case 3:
+ usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE;
+ break;
+ case 2:
+ usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE;
+ break;
+ case 1:
+ usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n",
+ __func__, usb_tx_cfg.bit_format,
+ ucontrol->value.integer.value[0]);
+
+ return rc;
+}
+
+const struct snd_kcontrol_new msm_common_snd_controls[] = {
+ SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs,
+ proxy_rx_ch_get, proxy_rx_ch_put),
+ SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate,
+ aux_pcm_rx_sample_rate_get,
+ aux_pcm_rx_sample_rate_put),
+ SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate,
+ aux_pcm_rx_sample_rate_get,
+ aux_pcm_rx_sample_rate_put),
+ SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate,
+ aux_pcm_rx_sample_rate_get,
+ aux_pcm_rx_sample_rate_put),
+ SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate,
+ aux_pcm_rx_sample_rate_get,
+ aux_pcm_rx_sample_rate_put),
+ SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate,
+ aux_pcm_tx_sample_rate_get,
+ aux_pcm_tx_sample_rate_put),
+ SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate,
+ aux_pcm_tx_sample_rate_get,
+ aux_pcm_tx_sample_rate_put),
+ SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate,
+ aux_pcm_tx_sample_rate_get,
+ aux_pcm_tx_sample_rate_put),
+ SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate,
+ aux_pcm_tx_sample_rate_get,
+ aux_pcm_tx_sample_rate_put),
+ SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate,
+ mi2s_rx_sample_rate_get,
+ mi2s_rx_sample_rate_put),
+ SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate,
+ mi2s_rx_sample_rate_get,
+ mi2s_rx_sample_rate_put),
+ SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate,
+ mi2s_rx_sample_rate_get,
+ mi2s_rx_sample_rate_put),
+ SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate,
+ mi2s_rx_sample_rate_get,
+ mi2s_rx_sample_rate_put),
+ SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate,
+ mi2s_tx_sample_rate_get,
+ mi2s_tx_sample_rate_put),
+ SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate,
+ mi2s_tx_sample_rate_get,
+ mi2s_tx_sample_rate_put),
+ SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate,
+ mi2s_tx_sample_rate_get,
+ mi2s_tx_sample_rate_put),
+ SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate,
+ mi2s_tx_sample_rate_get,
+ mi2s_tx_sample_rate_put),
+ SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs,
+ msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
+ SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs,
+ msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
+ SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs,
+ msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
+ SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs,
+ msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
+ SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs,
+ msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
+ SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs,
+ msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
+ SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs,
+ msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
+ SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs,
+ msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
+ SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs,
+ usb_audio_rx_ch_get, usb_audio_rx_ch_put),
+ SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs,
+ usb_audio_tx_ch_get, usb_audio_tx_ch_put),
+ SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format,
+ usb_audio_rx_format_get, usb_audio_rx_format_put),
+ SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format,
+ usb_audio_tx_format_get, usb_audio_tx_format_put),
+ SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate,
+ usb_audio_rx_sample_rate_get,
+ usb_audio_rx_sample_rate_put),
+ SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate,
+ usb_audio_tx_sample_rate_get,
+ usb_audio_tx_sample_rate_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
+ tdm_rx_sample_rate_get,
+ tdm_rx_sample_rate_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
+ tdm_tx_sample_rate_get,
+ tdm_tx_sample_rate_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format,
+ tdm_rx_format_get,
+ tdm_rx_format_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format,
+ tdm_tx_format_get,
+ tdm_tx_format_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs,
+ tdm_rx_ch_get,
+ tdm_rx_ch_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs,
+ tdm_tx_ch_get,
+ tdm_tx_ch_put),
+ SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
+ tdm_rx_sample_rate_get,
+ tdm_rx_sample_rate_put),
+ SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
+ tdm_tx_sample_rate_get,
+ tdm_tx_sample_rate_put),
+ SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format,
+ tdm_rx_format_get,
+ tdm_rx_format_put),
+ SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format,
+ tdm_tx_format_get,
+ tdm_tx_format_put),
+ SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs,
+ tdm_rx_ch_get,
+ tdm_rx_ch_put),
+ SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs,
+ tdm_tx_ch_get,
+ tdm_tx_ch_put),
+ SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
+ tdm_rx_sample_rate_get,
+ tdm_rx_sample_rate_put),
+ SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
+ tdm_tx_sample_rate_get,
+ tdm_tx_sample_rate_put),
+ SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format,
+ tdm_rx_format_get,
+ tdm_rx_format_put),
+ SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format,
+ tdm_tx_format_get,
+ tdm_tx_format_put),
+ SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs,
+ tdm_rx_ch_get,
+ tdm_rx_ch_put),
+ SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs,
+ tdm_tx_ch_get,
+ tdm_tx_ch_put),
+ SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
+ tdm_rx_sample_rate_get,
+ tdm_rx_sample_rate_put),
+ SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
+ tdm_tx_sample_rate_get,
+ tdm_tx_sample_rate_put),
+ SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format,
+ tdm_rx_format_get,
+ tdm_rx_format_put),
+ SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format,
+ tdm_tx_format_get,
+ tdm_tx_format_put),
+ SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs,
+ tdm_rx_ch_get,
+ tdm_rx_ch_put),
+ SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs,
+ tdm_tx_ch_get,
+ tdm_tx_ch_put),
+};
+
+static inline int param_is_mask(int p)
+{
+ return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
+ (p <= SNDRV_PCM_HW_PARAM_LAST_MASK);
+}
+
+static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p,
+ int n)
+{
+ return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
+}
+
+static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned bit)
+{
+ if (bit >= SNDRV_MASK_MAX)
+ return;
+ if (param_is_mask(n)) {
+ struct snd_mask *m = param_to_mask(p, n);
+
+ m->bits[0] = 0;
+ m->bits[1] = 0;
+ m->bits[bit >> 5] |= (1 << (bit & 31));
+ }
+}
+
+/**
+ * msm_common_be_hw_params_fixup - updates settings of ALSA BE hw params.
+ *
+ * @rtd: runtime dailink instance
+ * @params: HW params of associated backend dailink.
+ *
+ * Returns 0.
+ */
+int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+ int rc = 0;
+
+ pr_debug("%s: format = %d, rate = %d\n",
+ __func__, params_format(params), params_rate(params));
+
+ switch (dai_link->be_id) {
+ case MSM_BACKEND_DAI_USB_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ usb_rx_cfg.bit_format);
+ rate->min = rate->max = usb_rx_cfg.sample_rate;
+ channels->min = channels->max = usb_rx_cfg.channels;
+ break;
+
+ case MSM_BACKEND_DAI_USB_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ usb_tx_cfg.bit_format);
+ rate->min = rate->max = usb_tx_cfg.sample_rate;
+ channels->min = channels->max = usb_tx_cfg.channels;
+ break;
+
+ case MSM_BACKEND_DAI_AFE_PCM_RX:
+ channels->min = channels->max = proxy_rx_cfg.channels;
+ rate->min = rate->max = SAMPLING_RATE_48KHZ;
+ break;
+
+ case MSM_BACKEND_DAI_PRI_TDM_RX_0:
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_PRI][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_PRI][TDM_0].bit_format);
+ rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_PRI_TDM_TX_0:
+ channels->min = channels->max =
+ tdm_tx_cfg[TDM_PRI][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_tx_cfg[TDM_PRI][TDM_0].bit_format);
+ rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_SEC_TDM_RX_0:
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_SEC][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_SEC][TDM_0].bit_format);
+ rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_SEC_TDM_TX_0:
+ channels->min = channels->max =
+ tdm_tx_cfg[TDM_SEC][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_tx_cfg[TDM_SEC][TDM_0].bit_format);
+ rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_TERT_TDM_RX_0:
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_TERT][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_TERT][TDM_0].bit_format);
+ rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_TERT_TDM_TX_0:
+ channels->min = channels->max =
+ tdm_tx_cfg[TDM_TERT][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_tx_cfg[TDM_TERT][TDM_0].bit_format);
+ rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_QUAT_TDM_RX_0:
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format);
+ rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_QUAT_TDM_TX_0:
+ channels->min = channels->max =
+ tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format);
+ rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_AUXPCM_RX:
+ rate->min = rate->max =
+ aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_rx_cfg[PRIM_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_AUXPCM_TX:
+ rate->min = rate->max =
+ aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_tx_cfg[PRIM_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SEC_AUXPCM_RX:
+ rate->min = rate->max =
+ aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_rx_cfg[SEC_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SEC_AUXPCM_TX:
+ rate->min = rate->max =
+ aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_tx_cfg[SEC_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_TERT_AUXPCM_RX:
+ rate->min = rate->max =
+ aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_rx_cfg[TERT_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_TERT_AUXPCM_TX:
+ rate->min = rate->max =
+ aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_tx_cfg[TERT_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_QUAT_AUXPCM_RX:
+ rate->min = rate->max =
+ aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_rx_cfg[QUAT_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_QUAT_AUXPCM_TX:
+ rate->min = rate->max =
+ aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_tx_cfg[QUAT_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_PRI_MI2S_RX:
+ rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_rx_cfg[PRIM_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_PRI_MI2S_TX:
+ rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_tx_cfg[PRIM_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SECONDARY_MI2S_RX:
+ rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_rx_cfg[SEC_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SECONDARY_MI2S_TX:
+ rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_tx_cfg[SEC_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_TERTIARY_MI2S_RX:
+ rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_rx_cfg[TERT_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_TERTIARY_MI2S_TX:
+ rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_tx_cfg[TERT_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX:
+ rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_rx_cfg[QUAT_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX:
+ rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_tx_cfg[QUAT_MI2S].channels;
+ break;
+
+ default:
+ rate->min = rate->max = SAMPLING_RATE_48KHZ;
+ break;
+ }
+ return rc;
+}
+EXPORT_SYMBOL(msm_common_be_hw_params_fixup);
+
+/**
+ * msm_aux_pcm_snd_startup - startup ops of auxpcm.
+ *
+ * @substream: PCM stream pointer of associated backend dailink
+ *
+ * Returns 0 on success or -EINVAL on error.
+ */
+int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int index = cpu_dai->id - 1;
+ return ret = 0;
+
+ dev_dbg(rtd->card->dev,
+ "%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
+ __func__, substream->name, substream->stream,
+ cpu_dai->name, cpu_dai->id);
+
+ if (index < PRIM_AUX_PCM || index > QUAT_AUX_PCM) {
+ ret = -EINVAL;
+ dev_err(rtd->card->dev,
+ "%s: CPU DAI id (%d) out of range\n",
+ __func__, cpu_dai->id);
+ goto done;
+ }
+
+ mutex_lock(&auxpcm_intf_conf[index].lock);
+ if (++auxpcm_intf_conf[index].ref_cnt == 1) {
+ if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) {
+ mutex_lock(&mi2s_auxpcm_conf[index].lock);
+ iowrite32(1,
+ mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr);
+ mutex_unlock(&mi2s_auxpcm_conf[index].lock);
+ } else {
+ dev_err(rtd->card->dev,
+ "%s lpaif_tert_muxsel_virt_addr is NULL\n",
+ __func__);
+ ret = -EINVAL;
+ }
+ }
+ if (IS_ERR_VALUE(ret))
+ auxpcm_intf_conf[index].ref_cnt--;
+
+ mutex_unlock(&auxpcm_intf_conf[index].lock);
+
+done:
+ return ret;
+}
+EXPORT_SYMBOL(msm_aux_pcm_snd_startup);
+
+/**
+ * msm_aux_pcm_snd_shutdown - shutdown ops of auxpcm.
+ *
+ * @substream: PCM stream pointer of associated backend dailink
+ */
+void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ int index = rtd->cpu_dai->id - 1;
+
+ dev_dbg(rtd->card->dev,
+ "%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
+ __func__,
+ substream->name, substream->stream,
+ rtd->cpu_dai->name, rtd->cpu_dai->id);
+
+ if (index < PRIM_AUX_PCM || index > QUAT_AUX_PCM) {
+ dev_err(rtd->card->dev,
+ "%s: CPU DAI id (%d) out of range\n",
+ __func__, rtd->cpu_dai->id);
+ return;
+ }
+
+ mutex_lock(&auxpcm_intf_conf[index].lock);
+ if (--auxpcm_intf_conf[index].ref_cnt == 0) {
+ if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) {
+ mutex_lock(&mi2s_auxpcm_conf[index].lock);
+ iowrite32(0,
+ mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr);
+ mutex_unlock(&mi2s_auxpcm_conf[index].lock);
+ } else {
+ dev_err(rtd->card->dev,
+ "%s lpaif_tert_muxsel_virt_addr is NULL\n",
+ __func__);
+ auxpcm_intf_conf[index].ref_cnt++;
+ }
+ }
+ mutex_unlock(&auxpcm_intf_conf[index].lock);
+}
+EXPORT_SYMBOL(msm_aux_pcm_snd_shutdown);
+
+static int msm_get_port_id(int be_id)
+{
+ int afe_port_id;
+
+ switch (be_id) {
+ case MSM_BACKEND_DAI_PRI_MI2S_RX:
+ afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX;
+ break;
+ case MSM_BACKEND_DAI_PRI_MI2S_TX:
+ afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX;
+ break;
+ case MSM_BACKEND_DAI_SECONDARY_MI2S_RX:
+ afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX;
+ break;
+ case MSM_BACKEND_DAI_SECONDARY_MI2S_TX:
+ afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX;
+ break;
+ case MSM_BACKEND_DAI_TERTIARY_MI2S_RX:
+ afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX;
+ break;
+ case MSM_BACKEND_DAI_TERTIARY_MI2S_TX:
+ afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX;
+ break;
+ case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX:
+ afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX;
+ break;
+ case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX:
+ afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX;
+ break;
+ default:
+ pr_err("%s: Invalid be_id: %d\n", __func__, be_id);
+ afe_port_id = -EINVAL;
+ }
+
+ return afe_port_id;
+}
+
+static u32 get_mi2s_bits_per_sample(u32 bit_format)
+{
+ u32 bit_per_sample;
+
+ switch (bit_format) {
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ case SNDRV_PCM_FORMAT_S24_LE:
+ bit_per_sample = 32;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ bit_per_sample = 16;
+ break;
+ }
+
+ return bit_per_sample;
+}
+
+static void update_mi2s_clk_val(int dai_id, int stream)
+{
+ u32 bit_per_sample;
+
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ bit_per_sample =
+ get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format);
+ mi2s_clk[dai_id].clk_freq_in_hz =
+ mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample;
+ } else {
+ bit_per_sample =
+ get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format);
+ mi2s_clk[dai_id].clk_freq_in_hz =
+ mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample;
+ }
+
+ if (!mi2s_intf_conf[dai_id].msm_is_mi2s_master)
+ mi2s_clk[dai_id].clk_freq_in_hz = 0;
+}
+
+static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int port_id = 0;
+ int index = cpu_dai->id;
+
+ port_id = msm_get_port_id(rtd->dai_link->be_id);
+ if (IS_ERR_VALUE(port_id)) {
+ dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__);
+ ret = port_id;
+ goto done;
+ }
+
+ if (enable) {
+ update_mi2s_clk_val(index, substream->stream);
+ dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__,
+ mi2s_clk[index].clk_freq_in_hz);
+ }
+
+ mi2s_clk[index].enable = enable;
+ ret = afe_set_lpass_clock_v2(port_id,
+ &mi2s_clk[index]);
+ if (ret < 0) {
+ dev_err(rtd->card->dev,
+ "%s: afe lpass clock failed for port 0x%x , err:%d\n",
+ __func__, port_id, ret);
+ goto done;
+ }
+
+done:
+ return ret;
+}
+
+/**
+ * msm_mi2s_snd_startup - startup ops of mi2s.
+ *
+ * @substream: PCM stream pointer of associated backend dailink
+ *
+ * Returns 0 on success or -EINVAL on error.
+ */
+int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int index = cpu_dai->id;
+ unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
+
+ dev_dbg(rtd->card->dev,
+ "%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
+ __func__, substream->name, substream->stream,
+ cpu_dai->name, cpu_dai->id);
+
+ if (index < PRIM_MI2S || index > QUAT_MI2S) {
+ ret = -EINVAL;
+ dev_err(rtd->card->dev,
+ "%s: CPU DAI id (%d) out of range\n",
+ __func__, cpu_dai->id);
+ goto done;
+ }
+ /*
+ * Muxtex protection in case the same MI2S
+ * interface using for both TX and RX so
+ * that the same clock won't be enable twice.
+ */
+ mutex_lock(&mi2s_intf_conf[index].lock);
+ if (++mi2s_intf_conf[index].ref_cnt == 1) {
+ ret = msm_mi2s_set_sclk(substream, true);
+ if (IS_ERR_VALUE(ret)) {
+ dev_err(rtd->card->dev,
+ "%s: afe lpass clock failed to enable MI2S clock, err:%d\n",
+ __func__, ret);
+ goto clean_up;
+ }
+ if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) {
+ mutex_lock(&mi2s_auxpcm_conf[index].lock);
+ iowrite32(0,
+ mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr);
+ mutex_unlock(&mi2s_auxpcm_conf[index].lock);
+ } else {
+ dev_err(rtd->card->dev,
+ "%s lpaif_muxsel_virt_addr is NULL for dai %d\n",
+ __func__, index);
+ ret = -EINVAL;
+ goto clk_off;
+ }
+ /* Check if msm needs to provide the clock to the interface */
+ if (!mi2s_intf_conf[index].msm_is_mi2s_master)
+ fmt = SND_SOC_DAIFMT_CBM_CFM;
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (IS_ERR_VALUE(ret)) {
+ dev_err(rtd->card->dev,
+ "%s: set fmt cpu dai failed for MI2S (%d), err:%d\n",
+ __func__, index, ret);
+ goto clk_off;
+ }
+ }
+clk_off:
+ if (IS_ERR_VALUE(ret))
+ msm_mi2s_set_sclk(substream, false);
+clean_up:
+ if (IS_ERR_VALUE(ret))
+ mi2s_intf_conf[index].ref_cnt--;
+ mutex_unlock(&mi2s_intf_conf[index].lock);
+done:
+ return ret;
+}
+EXPORT_SYMBOL(msm_mi2s_snd_startup);
+
+/**
+ * msm_mi2s_snd_shutdown - shutdown ops of mi2s.
+ *
+ * @substream: PCM stream pointer of associated backend dailink
+ */
+void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
+{
+ int ret;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ int index = rtd->cpu_dai->id;
+
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+ if (index < PRIM_MI2S || index > QUAT_MI2S) {
+ pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index);
+ return;
+ }
+
+ mutex_lock(&mi2s_intf_conf[index].lock);
+ if (--mi2s_intf_conf[index].ref_cnt == 0) {
+ ret = msm_mi2s_set_sclk(substream, false);
+ if (ret < 0) {
+ pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n",
+ __func__, index, ret);
+ mi2s_intf_conf[index].ref_cnt++;
+ }
+ }
+ mutex_unlock(&mi2s_intf_conf[index].lock);
+}
+EXPORT_SYMBOL(msm_mi2s_snd_shutdown);
+
+/* Validate whether US EU switch is present or not */
+static int msm_prepare_us_euro(struct snd_soc_card *card)
+{
+ struct msm_asoc_mach_data *pdata =
+ snd_soc_card_get_drvdata(card);
+ int ret = 0;
+
+ if (pdata->us_euro_gpio >= 0) {
+ dev_dbg(card->dev, "%s: us_euro gpio request %d", __func__,
+ pdata->us_euro_gpio);
+ ret = gpio_request(pdata->us_euro_gpio, "TASHA_CODEC_US_EURO");
+ if (ret) {
+ dev_err(card->dev,
+ "%s: Failed to request codec US/EURO gpio %d error %d\n",
+ __func__, pdata->us_euro_gpio, ret);
+ }
+ }
+
+ return ret;
+}
+
+static bool msm_swap_gnd_mic(struct snd_soc_codec *codec)
+{
+ struct snd_soc_card *card = codec->component.card;
+ struct msm_asoc_mach_data *pdata =
+ snd_soc_card_get_drvdata(card);
+ int value = 0;
+
+ if (pdata->us_euro_gpio_p) {
+ value = msm_cdc_pinctrl_get_state(pdata->us_euro_gpio_p);
+ if (value)
+ msm_cdc_pinctrl_select_sleep_state(
+ pdata->us_euro_gpio_p);
+ else
+ msm_cdc_pinctrl_select_active_state(
+ pdata->us_euro_gpio_p);
+ } else if (pdata->us_euro_gpio >= 0) {
+ value = gpio_get_value_cansleep(pdata->us_euro_gpio);
+ gpio_set_value_cansleep(pdata->us_euro_gpio, !value);
+ }
+ pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value);
+ return true;
+}
+
+static int msm_populate_dai_link_component_of_node(
+ struct snd_soc_card *card)
+{
+ int i, index, ret = 0;
+ struct device *cdev = card->dev;
+ struct snd_soc_dai_link *dai_link = card->dai_link;
+ struct device_node *phandle;
+
+ if (!cdev) {
+ pr_err("%s: Sound card device memory NULL\n", __func__);
+ return -ENODEV;
+ }
+
+ for (i = 0; i < card->num_links; i++) {
+ if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node)
+ continue;
+
+ /* populate platform_of_node for snd card dai links */
+ if (dai_link[i].platform_name &&
+ !dai_link[i].platform_of_node) {
+ index = of_property_match_string(cdev->of_node,
+ "asoc-platform-names",
+ dai_link[i].platform_name);
+ if (index < 0) {
+ pr_err("%s: No match found for platform name: %s\n",
+ __func__, dai_link[i].platform_name);
+ ret = index;
+ goto cpu_dai;
+ }
+ phandle = of_parse_phandle(cdev->of_node,
+ "asoc-platform",
+ index);
+ if (!phandle) {
+ pr_err("%s: retrieving phandle for platform %s, index %d failed\n",
+ __func__, dai_link[i].platform_name,
+ index);
+ ret = -ENODEV;
+ goto err;
+ }
+ dai_link[i].platform_of_node = phandle;
+ dai_link[i].platform_name = NULL;
+ }
+cpu_dai:
+ /* populate cpu_of_node for snd card dai links */
+ if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) {
+ index = of_property_match_string(cdev->of_node,
+ "asoc-cpu-names",
+ dai_link[i].cpu_dai_name);
+ if (index < 0)
+ goto codec_dai;
+ phandle = of_parse_phandle(cdev->of_node, "asoc-cpu",
+ index);
+ if (!phandle) {
+ pr_err("%s: retrieving phandle for cpu dai %s failed\n",
+ __func__, dai_link[i].cpu_dai_name);
+ ret = -ENODEV;
+ goto err;
+ }
+ dai_link[i].cpu_of_node = phandle;
+ dai_link[i].cpu_dai_name = NULL;
+ }
+codec_dai:
+ /* populate codec_of_node for snd card dai links */
+ if (dai_link[i].codec_name && !dai_link[i].codec_of_node) {
+ index = of_property_match_string(cdev->of_node,
+ "asoc-codec-names",
+ dai_link[i].codec_name);
+ if (index < 0)
+ continue;
+ phandle = of_parse_phandle(cdev->of_node, "asoc-codec",
+ index);
+ if (!phandle) {
+ pr_err("%s: retrieving phandle for codec dai %s failed\n",
+ __func__, dai_link[i].codec_name);
+ ret = -ENODEV;
+ goto err;
+ }
+ dai_link[i].codec_of_node = phandle;
+ dai_link[i].codec_name = NULL;
+ }
+ }
+err:
+ return ret;
+}
+
+static int msm_wsa881x_init(struct snd_soc_component *component)
+{
+ u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106};
+ u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107};
+ unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200};
+ unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3};
+ struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
+ struct msm_asoc_mach_data *pdata;
+ struct snd_soc_dapm_context *dapm =
+ snd_soc_codec_get_dapm(codec);
+
+ if (!codec) {
+ pr_err("%s codec is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ if (!strcmp(component->name_prefix, "SpkrLeft")) {
+ dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n",
+ __func__, codec->component.name);
+ wsa881x_set_channel_map(codec, &spkleft_ports[0],
+ WSA881X_MAX_SWR_PORTS, &ch_mask[0],
+ &ch_rate[0]);
+ if (dapm->component) {
+ snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN");
+ snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR");
+ }
+ } else if (!strcmp(component->name_prefix, "SpkrRight")) {
+ dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n",
+ __func__, codec->component.name);
+ wsa881x_set_channel_map(codec, &spkright_ports[0],
+ WSA881X_MAX_SWR_PORTS, &ch_mask[0],
+ &ch_rate[0]);
+ if (dapm->component) {
+ snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN");
+ snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR");
+ }
+ } else {
+ dev_err(codec->dev, "%s: wrong codec name %s\n", __func__,
+ codec->component.name);
+ return -EINVAL;
+ }
+
+
+ pdata = snd_soc_card_get_drvdata(component->card);
+ if (pdata && pdata->codec_root)
+ wsa881x_codec_info_create_codec_entry(pdata->codec_root,
+ codec);
+ return 0;
+}
+
+
+static int msm_init_wsa_dev(struct platform_device *pdev,
+ struct snd_soc_card *card)
+{
+ struct device_node *wsa_of_node;
+ u32 wsa_max_devs;
+ u32 wsa_dev_cnt;
+ char *dev_name_str = NULL;
+ struct msm_wsa881x_dev_info *wsa881x_dev_info;
+ const char *wsa_auxdev_name_prefix[1];
+ int found = 0;
+ int i;
+ int ret;
+
+ /* Get maximum WSA device count for this platform */
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,wsa-max-devs", &wsa_max_devs);
+ if (ret) {
+ dev_dbg(&pdev->dev,
+ "%s: wsa-max-devs property missing in DT %s, ret = %d\n",
+ __func__, pdev->dev.of_node->full_name, ret);
+ goto err_dt;
+ }
+ if (wsa_max_devs == 0) {
+ dev_warn(&pdev->dev,
+ "%s: Max WSA devices is 0 for this target?\n",
+ __func__);
+ goto err_dt;
+ }
+
+ /* Get count of WSA device phandles for this platform */
+ wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node,
+ "qcom,wsa-devs", NULL);
+ if (wsa_dev_cnt == -ENOENT) {
+ dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n",
+ __func__);
+ goto err_dt;
+ } else if (wsa_dev_cnt <= 0) {
+ dev_err(&pdev->dev,
+ "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n",
+ __func__, wsa_dev_cnt);
+ ret = -EINVAL;
+ goto err_dt;
+ }
+
+ /*
+ * Expect total phandles count to be NOT less than maximum possible
+ * WSA count. However, if it is less, then assign same value to
+ * max count as well.
+ */
+ if (wsa_dev_cnt < wsa_max_devs) {
+ dev_dbg(&pdev->dev,
+ "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n",
+ __func__, wsa_max_devs, wsa_dev_cnt);
+ wsa_max_devs = wsa_dev_cnt;
+ }
+
+ /* Make sure prefix string passed for each WSA device */
+ ret = of_property_count_strings(pdev->dev.of_node,
+ "qcom,wsa-aux-dev-prefix");
+ if (ret != wsa_dev_cnt) {
+ dev_err(&pdev->dev,
+ "%s: expecting %d wsa prefix. Defined only %d in DT\n",
+ __func__, wsa_dev_cnt, ret);
+ ret = -EINVAL;
+ goto err_dt;
+ }
+
+ /*
+ * Alloc mem to store phandle and index info of WSA device, if already
+ * registered with ALSA core
+ */
+ wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs,
+ sizeof(struct msm_wsa881x_dev_info),
+ GFP_KERNEL);
+ if (!wsa881x_dev_info) {
+ ret = -ENOMEM;
+ goto err_mem;
+ }
+
+ /*
+ * search and check whether all WSA devices are already
+ * registered with ALSA core or not. If found a node, store
+ * the node and the index in a local array of struct for later
+ * use.
+ */
+ for (i = 0; i < wsa_dev_cnt; i++) {
+ wsa_of_node = of_parse_phandle(pdev->dev.of_node,
+ "qcom,wsa-devs", i);
+ if (unlikely(!wsa_of_node)) {
+ /* we should not be here */
+ dev_err(&pdev->dev,
+ "%s: wsa dev node is not present\n",
+ __func__);
+ ret = -EINVAL;
+ goto err_dev_node;
+ }
+ if (soc_find_component(wsa_of_node, NULL)) {
+ /* WSA device registered with ALSA core */
+ wsa881x_dev_info[found].of_node = wsa_of_node;
+ wsa881x_dev_info[found].index = i;
+ found++;
+ if (found == wsa_max_devs)
+ break;
+ }
+ }
+
+ if (found < wsa_max_devs) {
+ dev_dbg(&pdev->dev,
+ "%s: failed to find %d components. Found only %d\n",
+ __func__, wsa_max_devs, found);
+ return -EPROBE_DEFER;
+ }
+ dev_info(&pdev->dev,
+ "%s: found %d wsa881x devices registered with ALSA core\n",
+ __func__, found);
+
+ card->num_aux_devs = wsa_max_devs;
+ card->num_configs = wsa_max_devs;
+
+ /* Alloc array of AUX devs struct */
+ msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs,
+ sizeof(struct snd_soc_aux_dev),
+ GFP_KERNEL);
+ if (!msm_aux_dev) {
+ ret = -ENOMEM;
+ goto err_auxdev_mem;
+ }
+
+ /* Alloc array of codec conf struct */
+ msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs,
+ sizeof(struct snd_soc_codec_conf),
+ GFP_KERNEL);
+ if (!msm_codec_conf) {
+ ret = -ENOMEM;
+ goto err_codec_conf;
+ }
+
+ for (i = 0; i < card->num_aux_devs; i++) {
+ dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN,
+ GFP_KERNEL);
+ if (!dev_name_str) {
+ ret = -ENOMEM;
+ goto err_dev_str;
+ }
+
+ ret = of_property_read_string_index(pdev->dev.of_node,
+ "qcom,wsa-aux-dev-prefix",
+ wsa881x_dev_info[i].index,
+ wsa_auxdev_name_prefix);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "%s: failed to read wsa aux dev prefix, ret = %d\n",
+ __func__, ret);
+ ret = -EINVAL;
+ goto err_dt_prop;
+ }
+
+ snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i);
+ msm_aux_dev[i].name = dev_name_str;
+ msm_aux_dev[i].codec_name = NULL;
+ msm_aux_dev[i].codec_of_node =
+ wsa881x_dev_info[i].of_node;
+ msm_aux_dev[i].init = msm_wsa881x_init;
+ msm_codec_conf[i].dev_name = NULL;
+ msm_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0];
+ msm_codec_conf[i].of_node = wsa881x_dev_info[i].of_node;
+ }
+ card->codec_conf = msm_codec_conf;
+ card->aux_dev = msm_aux_dev;
+
+ return 0;
+
+err_dt_prop:
+ devm_kfree(&pdev->dev, dev_name_str);
+err_dev_str:
+ devm_kfree(&pdev->dev, msm_codec_conf);
+err_codec_conf:
+ devm_kfree(&pdev->dev, msm_aux_dev);
+err_auxdev_mem:
+err_dev_node:
+ devm_kfree(&pdev->dev, wsa881x_dev_info);
+err_mem:
+err_dt:
+ return ret;
+}
+
+static void msm_free_auxdev_mem(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ int i;
+
+ if (card->num_aux_devs > 0) {
+ for (i = 0; i < card->num_aux_devs; i++) {
+ kfree(msm_aux_dev[i].codec_name);
+ kfree(msm_codec_conf[i].dev_name);
+ kfree(msm_codec_conf[i].name_prefix);
+ }
+ }
+}
+
+static void i2s_auxpcm_init(struct platform_device *pdev)
+{
+ struct resource *muxsel;
+ int count;
+ u32 mi2s_master_slave[MI2S_MAX];
+ int ret;
+ char *str[PCM_I2S_SEL_MAX] = {
+ "lpaif_pri_mode_muxsel",
+ "lpaif_sec_mode_muxsel",
+ "lpaif_tert_mode_muxsel",
+ "lpaif_quat_mode_muxsel"
+ };
+
+ for (count = 0; count < MI2S_MAX; count++) {
+ mutex_init(&mi2s_intf_conf[count].lock);
+ mi2s_intf_conf[count].ref_cnt = 0;
+ }
+
+ for (count = 0; count < AUX_PCM_MAX; count++) {
+ mutex_init(&auxpcm_intf_conf[count].lock);
+ auxpcm_intf_conf[count].ref_cnt = 0;
+ }
+
+ for (count = 0; count < PCM_I2S_SEL_MAX; count++) {
+ mutex_init(&mi2s_auxpcm_conf[count].lock);
+ mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr = NULL;
+ }
+
+ for (count = 0; count < PCM_I2S_SEL_MAX; count++) {
+ muxsel = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ str[count]);
+ if (muxsel) {
+ mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr
+ = ioremap(muxsel->start, resource_size(muxsel));
+ }
+ }
+
+ ret = of_property_read_u32_array(pdev->dev.of_node,
+ "qcom,msm-mi2s-master",
+ mi2s_master_slave, MI2S_MAX);
+ if (ret) {
+ dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n",
+ __func__);
+ } else {
+ for (count = 0; count < MI2S_MAX; count++) {
+ mi2s_intf_conf[count].msm_is_mi2s_master =
+ mi2s_master_slave[count];
+ }
+ }
+}
+
+static void i2s_auxpcm_deinit(void)
+{
+ int count;
+
+ for (count = 0; count < PCM_I2S_SEL_MAX; count++)
+ if (mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr !=
+ NULL)
+ iounmap(
+ mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr);
+}
+
+static const struct of_device_id msmfalcon_asoc_machine_of_match[] = {
+ { .compatible = "qcom,msmfalcon-asoc-snd",
+ .data = "internal_codec"},
+ { .compatible = "qcom,msmfalcon-asoc-snd-tasha",
+ .data = "tasha_codec"},
+ { .compatible = "qcom,msmfalcon-asoc-snd-tavil",
+ .data = "tavil_codec"},
+ {},
+};
+
+static int msm_asoc_machine_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = NULL;
+ struct msm_asoc_mach_data *pdata = NULL;
+ const char *mclk = "qcom,msm-mclk-freq";
+ int ret = -EINVAL, id;
+ const struct of_device_id *match;
+
+ pdata = devm_kzalloc(&pdev->dev,
+ sizeof(struct msm_asoc_mach_data),
+ GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ match = of_match_node(msmfalcon_asoc_machine_of_match,
+ pdev->dev.of_node);
+ if (!match)
+ goto err;
+
+ ret = of_property_read_u32(pdev->dev.of_node, mclk, &id);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "%s: missing %s in dt node\n", __func__, mclk);
+ id = DEFAULT_MCLK_RATE;
+ }
+ pdata->mclk_freq = id;
+
+ if (!strcmp(match->data, "tasha_codec") ||
+ !strcmp(match->data, "tavil_codec")) {
+ if (!strcmp(match->data, "tasha_codec"))
+ pdata->snd_card_val = EXT_SND_CARD_TASHA;
+ else
+ pdata->snd_card_val = EXT_SND_CARD_TAVIL;
+ ret = msm_ext_cdc_init(pdev, pdata, &card, &mbhc_cfg);
+ if (ret)
+ goto err;
+ } else if (!strcmp(match->data, "internal_codec")) {
+ pdata->snd_card_val = INT_SND_CARD;
+ ret = msm_int_cdc_init(pdev, pdata, &card, &mbhc_cfg);
+ if (ret)
+ goto err;
+ } else {
+ dev_err(&pdev->dev,
+ "%s: Not a matching DT sound node\n", __func__);
+ goto err;
+ }
+ if (!card)
+ goto err;
+
+ if (pdata->snd_card_val == INT_SND_CARD) {
+ /*reading the gpio configurations from dtsi file*/
+ ret = msm_gpioset_initialize(CLIENT_WCD, &pdev->dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev,
+ "%s: error reading dtsi files%d\n",
+ __func__, ret);
+ goto err;
+ }
+ }
+
+ /*
+ * Parse US-Euro gpio info from DT. Report no error if us-euro
+ * entry is not found in DT file as some targets do not support
+ * US-Euro detection
+ */
+ pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node,
+ "qcom,us-euro-gpios", 0);
+ if (!gpio_is_valid(pdata->us_euro_gpio))
+ pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node,
+ "qcom,us-euro-gpios", 0);
+ if (!gpio_is_valid(pdata->us_euro_gpio) && (!pdata->us_euro_gpio_p)) {
+ dev_dbg(&pdev->dev, "property %s not detected in node %s",
+ "qcom,us-euro-gpios", pdev->dev.of_node->full_name);
+ } else {
+ dev_dbg(&pdev->dev, "%s detected",
+ "qcom,us-euro-gpios");
+ mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic;
+ }
+
+ ret = msm_prepare_us_euro(card);
+ if (ret)
+ dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n",
+ ret);
+
+ i2s_auxpcm_init(pdev);
+
+ ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing");
+ if (ret)
+ goto err;
+
+ ret = msm_populate_dai_link_component_of_node(card);
+ if (ret) {
+ ret = -EPROBE_DEFER;
+ goto err;
+ }
+ ret = msm_init_wsa_dev(pdev, card);
+ if (ret)
+ goto err;
+
+
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+ ret);
+ goto err;
+ }
+ if (pdata->snd_card_val != INT_SND_CARD)
+ msm_ext_register_audio_notifier();
+ return 0;
+err:
+ if (pdata->us_euro_gpio > 0) {
+ dev_dbg(&pdev->dev, "%s free us_euro gpio %d\n",
+ __func__, pdata->us_euro_gpio);
+ pdata->us_euro_gpio = 0;
+ }
+ if (pdata->hph_en1_gpio > 0) {
+ dev_dbg(&pdev->dev, "%s free hph_en1_gpio %d\n",
+ __func__, pdata->hph_en1_gpio);
+ gpio_free(pdata->hph_en1_gpio);
+ pdata->hph_en1_gpio = 0;
+ }
+ if (pdata->hph_en0_gpio > 0) {
+ dev_dbg(&pdev->dev, "%s free hph_en0_gpio %d\n",
+ __func__, pdata->hph_en0_gpio);
+ gpio_free(pdata->hph_en0_gpio);
+ pdata->hph_en0_gpio = 0;
+ }
+ devm_kfree(&pdev->dev, pdata);
+ return ret;
+}
+
+static int msm_asoc_machine_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+
+ if (pdata->snd_card_val == INT_SND_CARD)
+ mutex_destroy(&pdata->cdc_int_mclk0_mutex);
+ msm_free_auxdev_mem(pdev);
+
+ gpio_free(pdata->us_euro_gpio);
+ gpio_free(pdata->hph_en1_gpio);
+ gpio_free(pdata->hph_en0_gpio);
+ i2s_auxpcm_deinit();
+ snd_soc_unregister_card(card);
+ return 0;
+}
+
+static struct platform_driver msmfalcon_asoc_machine_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = msmfalcon_asoc_machine_of_match,
+ },
+ .probe = msm_asoc_machine_probe,
+ .remove = msm_asoc_machine_remove,
+};
+module_platform_driver(msmfalcon_asoc_machine_driver);
+
+MODULE_DESCRIPTION("ALSA SoC msm");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, msmfalcon_asoc_machine_of_match);
diff --git a/sound/soc/msm/msmfalcon-common.h b/sound/soc/msm/msmfalcon-common.h
new file mode 100644
index 000000000000..5f6b8592acec
--- /dev/null
+++ b/sound/soc/msm/msmfalcon-common.h
@@ -0,0 +1,103 @@
+/* Copyright (c) 2015-2016, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSM_COMMON
+#define __MSM_COMMON
+
+#include <sound/soc.h>
+#include <sound/q6afe-v2.h>
+#include "../codecs/wcd-mbhc-v2.h"
+
+#define SAMPLING_RATE_8KHZ 8000
+#define SAMPLING_RATE_11P025KHZ 11025
+#define SAMPLING_RATE_16KHZ 16000
+#define SAMPLING_RATE_22P05KHZ 22050
+#define SAMPLING_RATE_32KHZ 32000
+#define SAMPLING_RATE_44P1KHZ 44100
+#define SAMPLING_RATE_48KHZ 48000
+#define SAMPLING_RATE_88P2KHZ 88200
+#define SAMPLING_RATE_96KHZ 96000
+#define SAMPLING_RATE_176P4KHZ 176400
+#define SAMPLING_RATE_192KHZ 192000
+#define SAMPLING_RATE_352P8KHZ 352800
+#define SAMPLING_RATE_384KHZ 384000
+
+#define TDM_CHANNEL_MAX 8
+#define TDM_SLOT_OFFSET_MAX 8
+
+enum {
+ TDM_0 = 0,
+ TDM_1,
+ TDM_2,
+ TDM_3,
+ TDM_4,
+ TDM_5,
+ TDM_6,
+ TDM_7,
+ TDM_PORT_MAX,
+};
+
+enum {
+ TDM_PRI = 0,
+ TDM_SEC,
+ TDM_TERT,
+ TDM_QUAT,
+ TDM_INTERFACE_MAX,
+};
+
+struct tdm_port {
+ u32 mode;
+ u32 channel;
+};
+
+extern const struct snd_kcontrol_new msm_common_snd_controls[];
+struct msmfalcon_codec {
+ void* (*get_afe_config_fn)(struct snd_soc_codec *codec,
+ enum afe_config_type config_type);
+};
+
+enum {
+ INT_SND_CARD,
+ EXT_SND_CARD_TASHA,
+ EXT_SND_CARD_TAVIL,
+};
+
+struct msm_asoc_mach_data {
+ int us_euro_gpio; /* used by gpio driver API */
+ int hph_en1_gpio;
+ int hph_en0_gpio;
+ struct device_node *us_euro_gpio_p; /* used by pinctrl API */
+ struct device_node *hph_en1_gpio_p; /* used by pinctrl API */
+ struct device_node *hph_en0_gpio_p; /* used by pinctrl API */
+ struct snd_soc_codec *codec;
+ struct msmfalcon_codec msmfalcon_codec_fn;
+ struct snd_info_entry *codec_root;
+ int spk_ext_pa_gpio;
+ int mclk_freq;
+ int lb_mode;
+ int snd_card_val;
+ u8 micbias1_cap_mode;
+ u8 micbias2_cap_mode;
+ atomic_t int_mclk0_rsc_ref;
+ atomic_t int_mclk0_enabled;
+ struct mutex cdc_int_mclk0_mutex;
+ struct delayed_work disable_int_mclk0_work;
+ struct afe_clk_set digital_cdc_core_clk;
+};
+
+int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params);
+int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream);
+void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream);
+int msm_mi2s_snd_startup(struct snd_pcm_substream *substream);
+void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream);
+#endif
diff --git a/sound/soc/msm/msmfalcon-ext-dai-links.c b/sound/soc/msm/msmfalcon-ext-dai-links.c
new file mode 100644
index 000000000000..6f066c5945a9
--- /dev/null
+++ b/sound/soc/msm/msmfalcon-ext-dai-links.c
@@ -0,0 +1,1967 @@
+/* Copyright (c) 2015-2016, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/mfd/wcd9xxx/core.h>
+#include <linux/of.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include "qdsp6v2/msm-pcm-routing-v2.h"
+#include "../codecs/wcd9335.h"
+#include "msmfalcon-common.h"
+#include "msmfalcon-external.h"
+
+#define DEV_NAME_STR_LEN 32
+#define __CHIPSET__ "MSMFALCON "
+#define MSM_DAILINK_NAME(name) (__CHIPSET__#name)
+
+#define WCN_CDC_SLIM_RX_CH_MAX 2
+#define WCN_CDC_SLIM_TX_CH_MAX 3
+
+static struct snd_soc_card snd_soc_card_msm_card_tavil;
+static struct snd_soc_card snd_soc_card_msm_card_tasha;
+
+static struct snd_soc_ops msm_ext_slimbus_be_ops = {
+ .hw_params = msm_snd_hw_params,
+};
+
+static struct snd_soc_ops msm_ext_cpe_ops = {
+ .hw_params = msm_snd_cpe_hw_params,
+};
+
+static struct snd_soc_ops msm_ext_slimbus_2_be_ops = {
+ .hw_params = msm_ext_slimbus_2_hw_params,
+};
+
+static struct snd_soc_ops msm_mi2s_be_ops = {
+ .startup = msm_mi2s_snd_startup,
+ .shutdown = msm_mi2s_snd_shutdown,
+};
+
+static struct snd_soc_ops msm_aux_pcm_be_ops = {
+ .startup = msm_aux_pcm_snd_startup,
+ .shutdown = msm_aux_pcm_snd_shutdown,
+};
+
+static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd)
+{
+ unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158};
+ unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161};
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+
+ return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
+ tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
+}
+
+static int msm_wcn_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+ u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX];
+ u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
+ int ret;
+
+ dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__,
+ codec_dai->name, codec_dai->id);
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
+ if (ret) {
+ dev_err(rtd->dev,
+ "%s: failed to get BTFM codec chan map\n, err:%d\n",
+ __func__, ret);
+ goto exit;
+ }
+
+ dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) be_id %d\n",
+ __func__, tx_ch_cnt, dai_link->be_id);
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch);
+ if (ret)
+ dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n",
+ __func__, ret);
+
+exit:
+ return ret;
+}
+
+static struct snd_soc_ops msm_wcn_ops = {
+ .hw_params = msm_wcn_hw_params,
+};
+
+/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */
+static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = {
+ {0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */
+ {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */
+ {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */
+ {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */
+ {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */
+ {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */
+ {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */
+ {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */
+};
+
+static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width,
+ int slots)
+{
+ unsigned int slot_mask = 0;
+ int i, j;
+ unsigned int *slot_offset;
+
+ for (i = TDM_0; i < TDM_PORT_MAX; i++) {
+ slot_offset = tdm_slot_offset[i];
+
+ for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) {
+ if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID)
+ slot_mask |=
+ (1 << ((slot_offset[j] * 8) / slot_width));
+ else
+ break;
+ }
+ }
+
+ return slot_mask;
+}
+
+static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+ int channels, slot_width, slots;
+ unsigned int slot_mask;
+ unsigned int *slot_offset;
+ int offset_channels = 0;
+ int i;
+
+ pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
+
+ channels = params_channels(params);
+ switch (channels) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ case SNDRV_PCM_FORMAT_S24_LE:
+ case SNDRV_PCM_FORMAT_S16_LE:
+ /*
+ * up to 8 channels HW config should
+ * use 32 bit slot width for max support of
+ * stream bit width. (slot_width > bit_width)
+ */
+ slot_width = 32;
+ break;
+ default:
+ pr_err("%s: invalid param format 0x%x\n",
+ __func__, params_format(params));
+ return -EINVAL;
+ }
+ slots = 8;
+ slot_mask = tdm_param_set_slot_mask(cpu_dai->id,
+ slot_width,
+ slots);
+ if (!slot_mask) {
+ pr_err("%s: invalid slot_mask 0x%x\n",
+ __func__, slot_mask);
+ return -EINVAL;
+ }
+ break;
+ default:
+ pr_err("%s: invalid param channels %d\n",
+ __func__, channels);
+ return -EINVAL;
+ }
+ /* currently only supporting TDM_RX_0 and TDM_TX_0 */
+ switch (cpu_dai->id) {
+ case AFE_PORT_ID_PRIMARY_TDM_RX:
+ case AFE_PORT_ID_SECONDARY_TDM_RX:
+ case AFE_PORT_ID_TERTIARY_TDM_RX:
+ case AFE_PORT_ID_QUATERNARY_TDM_RX:
+ case AFE_PORT_ID_PRIMARY_TDM_TX:
+ case AFE_PORT_ID_SECONDARY_TDM_TX:
+ case AFE_PORT_ID_TERTIARY_TDM_TX:
+ case AFE_PORT_ID_QUATERNARY_TDM_TX:
+ slot_offset = tdm_slot_offset[TDM_0];
+ break;
+ default:
+ pr_err("%s: dai id 0x%x not supported\n",
+ __func__, cpu_dai->id);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) {
+ if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID)
+ offset_channels++;
+ else
+ break;
+ }
+
+ if (offset_channels == 0) {
+ pr_err("%s: slot offset not supported, offset_channels %d\n",
+ __func__, offset_channels);
+ return -EINVAL;
+ }
+
+ if (channels > offset_channels) {
+ pr_err("%s: channels %d exceed offset_channels %d\n",
+ __func__, channels, offset_channels);
+ return -EINVAL;
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
+ slots, slot_width);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm slot, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
+ channels, slot_offset);
+ if (ret < 0) {
+ pr_err("%s: failed to set channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ } else {
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0,
+ slots, slot_width);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm slot, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai, channels,
+ slot_offset, 0, NULL);
+ if (ret < 0) {
+ pr_err("%s: failed to set channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ }
+end:
+ return ret;
+}
+
+static struct snd_soc_ops msm_tdm_be_ops = {
+ .hw_params = msm_tdm_snd_hw_params
+};
+
+static struct snd_soc_dai_link msm_ext_tasha_fe_dai[] = {
+ /* tasha_vifeedback for speaker protection */
+ {
+ .name = LPASS_BE_SLIMBUS_4_TX,
+ .stream_name = "Slimbus4 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16393",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_vifeedback",
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ },
+ /* Ultrasound RX DAI Link */
+ {
+ .name = "SLIMBUS_2 Hostless Playback",
+ .stream_name = "SLIMBUS_2 Hostless Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16388",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_rx2",
+ .ignore_suspend = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ops = &msm_ext_slimbus_2_be_ops,
+ },
+ /* Ultrasound TX DAI Link */
+ {
+ .name = "SLIMBUS_2 Hostless Capture",
+ .stream_name = "SLIMBUS_2 Hostless Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16389",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_tx2",
+ .ignore_suspend = 1,
+ .dpcm_capture = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ops = &msm_ext_slimbus_2_be_ops,
+ },
+ /* CPE LSM direct dai-link */
+ {
+ .name = "CPE Listen service",
+ .stream_name = "CPE Listen Audio Service",
+ .cpu_dai_name = "msm-dai-slim",
+ .platform_name = "msm-cpe-lsm",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .dpcm_capture = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "tasha_mad1",
+ .codec_name = "tasha_codec",
+ .ops = &msm_ext_cpe_ops,
+ },
+ {
+ .name = "SLIMBUS_6 Hostless Playback",
+ .stream_name = "SLIMBUS_6 Hostless",
+ .cpu_dai_name = "SLIMBUS6_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dailink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ /* CPE LSM EC PP direct dai-link */
+ {
+ .name = "CPE Listen service ECPP",
+ .stream_name = "CPE Listen Audio Service ECPP",
+ .cpu_dai_name = "CPE_LSM_NOHOST",
+ .platform_name = "msm-cpe-lsm.3",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "tasha_cpe",
+ .codec_name = "tasha_codec",
+ },
+};
+
+static struct snd_soc_dai_link msm_ext_tavil_fe_dai[] = {
+ {
+ .name = LPASS_BE_SLIMBUS_4_TX,
+ .stream_name = "Slimbus4 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16393",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_vifeedback",
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ },
+ /* Ultrasound RX DAI Link */
+ {
+ .name = "SLIMBUS_2 Hostless Playback",
+ .stream_name = "SLIMBUS_2 Hostless Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16388",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx2",
+ .ignore_suspend = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ops = &msm_ext_slimbus_2_be_ops,
+ },
+ /* Ultrasound TX DAI Link */
+ {
+ .name = "SLIMBUS_2 Hostless Capture",
+ .stream_name = "SLIMBUS_2 Hostless Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16389",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_tx2",
+ .ignore_suspend = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ops = &msm_ext_slimbus_2_be_ops,
+ },
+};
+
+static struct snd_soc_dai_link msm_ext_tasha_be_dai[] = {
+ /* Backend DAI Links */
+ {
+ .name = LPASS_BE_SLIMBUS_0_RX,
+ .stream_name = "Slimbus Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16384",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_mix_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ .init = &msm_audrx_init,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ .ops = &msm_ext_slimbus_be_ops,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_0_TX,
+ .stream_name = "Slimbus Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16385",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_tx1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ .ops = &msm_ext_slimbus_be_ops,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_1_RX,
+ .stream_name = "Slimbus1 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16386",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_mix_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_1_RX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_1_TX,
+ .stream_name = "Slimbus1 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16387",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_tx3",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_3_RX,
+ .stream_name = "Slimbus3 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16390",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_mix_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_3_RX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_3_TX,
+ .stream_name = "Slimbus3 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16391",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_tx1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_4_RX,
+ .stream_name = "Slimbus4 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16392",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_mix_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_4_RX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_5_RX,
+ .stream_name = "Slimbus5 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16394",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_rx3",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_5_RX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ /* MAD BE */
+ {
+ .name = LPASS_BE_SLIMBUS_5_TX,
+ .stream_name = "Slimbus5 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16395",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_mad1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_5_TX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_6_RX,
+ .stream_name = "Slimbus6 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16396",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_rx4",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_6_RX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+};
+
+static struct snd_soc_dai_link msm_ext_tavil_be_dai[] = {
+ {
+ .name = LPASS_BE_SLIMBUS_0_RX,
+ .stream_name = "Slimbus Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16384",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ .init = &msm_audrx_init,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ .ops = &msm_ext_slimbus_be_ops,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_0_TX,
+ .stream_name = "Slimbus Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16385",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_tx1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ .ops = &msm_ext_slimbus_be_ops,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_1_RX,
+ .stream_name = "Slimbus1 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16386",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_1_RX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_1_TX,
+ .stream_name = "Slimbus1 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16387",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_tx3",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_2_RX,
+ .stream_name = "Slimbus2 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16388",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx2",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_3_RX,
+ .stream_name = "Slimbus3 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16390",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_3_RX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_3_TX,
+ .stream_name = "Slimbus3 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16391",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_tx1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_4_RX,
+ .stream_name = "Slimbus4 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16392",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_4_RX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_5_RX,
+ .stream_name = "Slimbus5 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16394",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx3",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_5_RX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ /* MAD BE */
+ {
+ .name = LPASS_BE_SLIMBUS_5_TX,
+ .stream_name = "Slimbus5 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16395",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_mad1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_5_TX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_6_RX,
+ .stream_name = "Slimbus6 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16396",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx4",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_6_RX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_ext_slimbus_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+};
+
+static struct snd_soc_dai_link msm_ext_common_fe_dai[] = {
+ /* FrontEnd DAI Links */
+ {/* hw:x,0 */
+ .name = MSM_DAILINK_NAME(Media1),
+ .stream_name = "MultiMedia1",
+ .cpu_dai_name = "MultiMedia1",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA1
+ },
+ {/* hw:x,1 */
+ .name = MSM_DAILINK_NAME(Media2),
+ .stream_name = "MultiMedia2",
+ .cpu_dai_name = "MultiMedia2",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA2,
+ },
+ {/* hw:x,2 */
+ .name = "VoiceMMode1",
+ .stream_name = "VoiceMMode1",
+ .cpu_dai_name = "VoiceMMode1",
+ .platform_name = "msm-pcm-voice",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_VOICEMMODE1,
+ },
+ {/* hw:x,3 */
+ .name = "MSM VoIP",
+ .stream_name = "VoIP",
+ .cpu_dai_name = "VoIP",
+ .platform_name = "msm-voip-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_VOIP,
+ },
+ {/* hw:x,4 */
+ .name = MSM_DAILINK_NAME(ULL),
+ .stream_name = "ULL",
+ .cpu_dai_name = "MultiMedia3",
+ .platform_name = "msm-pcm-dsp.2",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA3,
+ },
+ /* Hostless PCM purpose */
+ {/* hw:x,5 */
+ .name = "SLIMBUS_0 Hostless",
+ .stream_name = "SLIMBUS_0 Hostless",
+ .cpu_dai_name = "SLIMBUS0_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* This dai link has MI2S support */
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,6 */
+ .name = "MSM AFE-PCM RX",
+ .stream_name = "AFE-PROXY RX",
+ .cpu_dai_name = "msm-dai-q6-dev.241",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .platform_name = "msm-pcm-afe",
+ .ignore_suspend = 1,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ },
+ {/* hw:x,7 */
+ .name = "MSM AFE-PCM TX",
+ .stream_name = "AFE-PROXY TX",
+ .cpu_dai_name = "msm-dai-q6-dev.240",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .platform_name = "msm-pcm-afe",
+ .ignore_suspend = 1,
+ },
+ {/* hw:x,8 */
+ .name = MSM_DAILINK_NAME(Compress1),
+ .stream_name = "Compress1",
+ .cpu_dai_name = "MultiMedia4",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA4,
+ },
+ {/* hw:x,9*/
+ .name = "AUXPCM Hostless",
+ .stream_name = "AUXPCM Hostless",
+ .cpu_dai_name = "AUXPCM_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,10 */
+ .name = "SLIMBUS_1 Hostless",
+ .stream_name = "SLIMBUS_1 Hostless",
+ .cpu_dai_name = "SLIMBUS1_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1, /* dai link has playback support */
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,11 */
+ .name = "SLIMBUS_3 Hostless",
+ .stream_name = "SLIMBUS_3 Hostless",
+ .cpu_dai_name = "SLIMBUS3_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1, /* dai link has playback support */
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,12 */
+ .name = "SLIMBUS_4 Hostless",
+ .stream_name = "SLIMBUS_4 Hostless",
+ .cpu_dai_name = "SLIMBUS4_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1, /* dai link has playback support */
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,13 */
+ .name = MSM_DAILINK_NAME(LowLatency),
+ .stream_name = "MultiMedia5",
+ .cpu_dai_name = "MultiMedia5",
+ .platform_name = "msm-pcm-dsp.1",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA5,
+ },
+ /* LSM FE */
+ {/* hw:x,14 */
+ .name = "Listen 1 Audio Service",
+ .stream_name = "Listen 1 Audio Service",
+ .cpu_dai_name = "LSM1",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM1,
+ },
+ {/* hw:x,15 */
+ .name = MSM_DAILINK_NAME(Compress2),
+ .stream_name = "Compress2",
+ .cpu_dai_name = "MultiMedia7",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA7,
+ },
+ {/* hw:x,16 */
+ .name = MSM_DAILINK_NAME(Compress3),
+ .stream_name = "Compress3",
+ .cpu_dai_name = "MultiMedia10",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA10,
+ },
+ {/* hw:x,17 */
+ .name = MSM_DAILINK_NAME(ULL_NOIRQ),
+ .stream_name = "MM_NOIRQ",
+ .cpu_dai_name = "MultiMedia8",
+ .platform_name = "msm-pcm-dsp-noirq",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
+ },
+ {/* hw:x,18 */
+ .name = "HDMI_RX_HOSTLESS",
+ .stream_name = "HDMI_RX_HOSTLESS",
+ .cpu_dai_name = "HDMI_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,19 */
+ .name = "VoiceMMode2",
+ .stream_name = "VoiceMMode2",
+ .cpu_dai_name = "VoiceMMode2",
+ .platform_name = "msm-pcm-voice",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_VOICEMMODE2,
+ },
+ {/* hw:x,20 */
+ .name = "Listen 2 Audio Service",
+ .stream_name = "Listen 2 Audio Service",
+ .cpu_dai_name = "LSM2",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM2,
+ },
+ {/* hw:x,21 */
+ .name = "Listen 3 Audio Service",
+ .stream_name = "Listen 3 Audio Service",
+ .cpu_dai_name = "LSM3",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM3,
+ },
+ {/* hw:x,22 */
+ .name = "Listen 4 Audio Service",
+ .stream_name = "Listen 4 Audio Service",
+ .cpu_dai_name = "LSM4",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM4,
+ },
+ {/* hw:x,23 */
+ .name = "Listen 5 Audio Service",
+ .stream_name = "Listen 5 Audio Service",
+ .cpu_dai_name = "LSM5",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM5,
+ },
+ {/* hw:x,24 */
+ .name = "Listen 6 Audio Service",
+ .stream_name = "Listen 6 Audio Service",
+ .cpu_dai_name = "LSM6",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM6
+ },
+ {/* hw:x,25 */
+ .name = "Listen 7 Audio Service",
+ .stream_name = "Listen 7 Audio Service",
+ .cpu_dai_name = "LSM7",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM7,
+ },
+ {/* hw:x,26 */
+ .name = "Listen 8 Audio Service",
+ .stream_name = "Listen 8 Audio Service",
+ .cpu_dai_name = "LSM8",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM8,
+ },
+ {/* hw:x,27 */
+ .name = MSM_DAILINK_NAME(Media9),
+ .stream_name = "MultiMedia9",
+ .cpu_dai_name = "MultiMedia9",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA9,
+ },
+ {/* hw:x,28 */
+ .name = MSM_DAILINK_NAME(Compress4),
+ .stream_name = "Compress4",
+ .cpu_dai_name = "MultiMedia11",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA11,
+ },
+ {/* hw:x,29 */
+ .name = MSM_DAILINK_NAME(Compress5),
+ .stream_name = "Compress5",
+ .cpu_dai_name = "MultiMedia12",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA12,
+ },
+ {/* hw:x,30 */
+ .name = MSM_DAILINK_NAME(Compress6),
+ .stream_name = "Compress6",
+ .cpu_dai_name = "MultiMedia13",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA13,
+ },
+ {/* hw:x,31 */
+ .name = MSM_DAILINK_NAME(Compress7),
+ .stream_name = "Compress7",
+ .cpu_dai_name = "MultiMedia14",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA14,
+ },
+ {/* hw:x,32 */
+ .name = MSM_DAILINK_NAME(Compress8),
+ .stream_name = "Compress8",
+ .cpu_dai_name = "MultiMedia15",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA15,
+ },
+ {/* hw:x,33 */
+ .name = MSM_DAILINK_NAME(Compress9),
+ .stream_name = "Compress9",
+ .cpu_dai_name = "MultiMedia16",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA16,
+ },
+ {/* hw:x,34 */
+ .name = "SLIMBUS_8 Hostless",
+ .stream_name = "SLIMBUS8_HOSTLESS Capture",
+ .cpu_dai_name = "SLIMBUS8_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+};
+
+static struct snd_soc_dai_link msm_ext_common_be_dai[] = {
+ {
+ .name = LPASS_BE_AFE_PCM_RX,
+ .stream_name = "AFE Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.224",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_AFE_PCM_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_AFE_PCM_TX,
+ .stream_name = "AFE Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.225",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_AFE_PCM_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Incall Record Uplink BACK END DAI Link */
+ {
+ .name = LPASS_BE_INCALL_RECORD_TX,
+ .stream_name = "Voice Uplink Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.32772",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_INCALL_RECORD_TX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Incall Record Downlink BACK END DAI Link */
+ {
+ .name = LPASS_BE_INCALL_RECORD_RX,
+ .stream_name = "Voice Downlink Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.32771",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_INCALL_RECORD_RX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Incall Music BACK END DAI Link */
+ {
+ .name = LPASS_BE_VOICE_PLAYBACK_TX,
+ .stream_name = "Voice Farend Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.32773",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Incall Music 2 BACK END DAI Link */
+ {
+ .name = LPASS_BE_VOICE2_PLAYBACK_TX,
+ .stream_name = "Voice2 Farend Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.32770",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_USB_AUDIO_RX,
+ .stream_name = "USB Audio Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.28672",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_USB_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_USB_AUDIO_TX,
+ .stream_name = "USB Audio Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.28673",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_USB_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_TDM_RX_0,
+ .stream_name = "Primary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36864",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_TDM_TX_0,
+ .stream_name = "Primary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36865",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_TDM_RX_0,
+ .stream_name = "Secondary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36880",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_TDM_TX_0,
+ .stream_name = "Secondary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36881",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_TDM_RX_0,
+ .stream_name = "Tertiary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36896",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_TDM_TX_0,
+ .stream_name = "Tertiary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36897",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_TDM_RX_0,
+ .stream_name = "Quaternary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36912",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_TDM_TX_0,
+ .stream_name = "Quaternary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36913",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+};
+
+static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = {
+ {
+ .name = LPASS_BE_PRI_MI2S_RX,
+ .stream_name = "Primary MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.0",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_MI2S_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_MI2S_TX,
+ .stream_name = "Primary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.0",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_MI2S_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_MI2S_RX,
+ .stream_name = "Secondary MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_MI2S_TX,
+ .stream_name = "Secondary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_MI2S_RX,
+ .stream_name = "Tertiary MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.2",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_MI2S_TX,
+ .stream_name = "Tertiary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.2",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_RX,
+ .stream_name = "Quaternary MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_TX,
+ .stream_name = "Quaternary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+};
+
+static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = {
+ /* Primary AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_AUXPCM_RX,
+ .stream_name = "AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_AUXPCM_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+ {
+ .name = LPASS_BE_AUXPCM_TX,
+ .stream_name = "AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_AUXPCM_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+ /* Secondary AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_SEC_AUXPCM_RX,
+ .stream_name = "Sec AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.2",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+ {
+ .name = LPASS_BE_SEC_AUXPCM_TX,
+ .stream_name = "Sec AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.2",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+ /* Tertiary AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_TERT_AUXPCM_RX,
+ .stream_name = "Tert AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+ {
+ .name = LPASS_BE_TERT_AUXPCM_TX,
+ .stream_name = "Tert AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+ /* Quaternary AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_QUAT_AUXPCM_RX,
+ .stream_name = "Quat AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.4",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+ {
+ .name = LPASS_BE_QUAT_AUXPCM_TX,
+ .stream_name = "Quat AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.4",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+};
+
+static struct snd_soc_dai_link msm_wcn_be_dai_links[] = {
+ {
+ .name = LPASS_BE_SLIMBUS_7_RX,
+ .stream_name = "Slimbus7 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16398",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "btfmslim_slave",
+ /* BT codec driver determines capabilities based on
+ * dai name, bt codecdai name should always contains
+ * supported usecase information
+ */
+ .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_7_RX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_wcn_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_7_TX,
+ .stream_name = "Slimbus7 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16399",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "btfmslim_slave",
+ .codec_dai_name = "btfm_bt_sco_slim_tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_7_TX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .ops = &msm_wcn_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_8_TX,
+ .stream_name = "Slimbus8 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16401",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "btfmslim_slave",
+ .codec_dai_name = "btfm_fm_slim_tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_8_TX,
+ .be_hw_params_fixup = msm_ext_be_hw_params_fixup,
+ .init = &msm_wcn_init,
+ .ops = &msm_wcn_ops,
+ .ignore_suspend = 1,
+ },
+};
+
+static struct snd_soc_dai_link msm_ext_tasha_dai_links[
+ARRAY_SIZE(msm_ext_common_fe_dai) +
+ARRAY_SIZE(msm_ext_tasha_fe_dai) +
+ARRAY_SIZE(msm_ext_common_be_dai) +
+ARRAY_SIZE(msm_ext_tasha_be_dai) +
+ARRAY_SIZE(msm_mi2s_be_dai_links) +
+ARRAY_SIZE(msm_auxpcm_be_dai_links) +
+ARRAY_SIZE(msm_wcn_be_dai_links)];
+
+static struct snd_soc_dai_link msm_ext_tavil_dai_links[
+ARRAY_SIZE(msm_ext_common_fe_dai) +
+ARRAY_SIZE(msm_ext_tavil_fe_dai) +
+ARRAY_SIZE(msm_ext_common_be_dai) +
+ARRAY_SIZE(msm_ext_tavil_be_dai) +
+ARRAY_SIZE(msm_mi2s_be_dai_links) +
+ARRAY_SIZE(msm_auxpcm_be_dai_links) +
+ARRAY_SIZE(msm_wcn_be_dai_links)];
+
+/**
+ * populate_snd_card_dailinks - prepares dailink array and initializes card.
+ *
+ * @dev: device handle
+ *
+ * Returns card on success or NULL on failure.
+ */
+struct snd_soc_card *populate_snd_card_dailinks(struct device *dev,
+ int snd_card_val)
+{
+ struct snd_soc_card *card;
+ struct snd_soc_dai_link *msm_ext_dai_links = NULL;
+ int ret, len1, len2, len3, len4;
+ enum codec_variant codec_ver = 0;
+
+ if (snd_card_val == EXT_SND_CARD_TASHA) {
+ card = &snd_soc_card_msm_card_tasha;
+ } else if (snd_card_val == EXT_SND_CARD_TAVIL) {
+ card = &snd_soc_card_msm_card_tavil;
+ } else {
+ dev_err(dev, "%s: failing as no matching card name\n",
+ __func__);
+ return NULL;
+ }
+
+ card->dev = dev;
+ ret = snd_soc_of_parse_card_name(card, "qcom,model");
+ if (ret) {
+ dev_err(dev, "%s: parse card name failed, err:%d\n",
+ __func__, ret);
+ return NULL;
+ }
+
+ if (strnstr(card->name, "tasha", strlen(card->name))) {
+ codec_ver = tasha_codec_ver();
+ if (codec_ver == WCD9326)
+ card->name = "msmfalcon-tashalite-snd-card";
+
+ len1 = ARRAY_SIZE(msm_ext_common_fe_dai);
+ len2 = len1 + ARRAY_SIZE(msm_ext_tasha_fe_dai);
+ len3 = len2 + ARRAY_SIZE(msm_ext_common_be_dai);
+ memcpy(msm_ext_tasha_dai_links, msm_ext_common_fe_dai,
+ sizeof(msm_ext_common_fe_dai));
+ memcpy(msm_ext_tasha_dai_links + len1,
+ msm_ext_tasha_fe_dai, sizeof(msm_ext_tasha_fe_dai));
+ memcpy(msm_ext_tasha_dai_links + len2,
+ msm_ext_common_be_dai, sizeof(msm_ext_common_be_dai));
+ memcpy(msm_ext_tasha_dai_links + len3,
+ msm_ext_tasha_be_dai, sizeof(msm_ext_tasha_be_dai));
+ len4 = len3 + ARRAY_SIZE(msm_ext_tasha_be_dai);
+ if (of_property_read_bool(dev->of_node,
+ "qcom,mi2s-audio-intf")) {
+ memcpy(msm_ext_tasha_dai_links + len4,
+ msm_mi2s_be_dai_links,
+ sizeof(msm_mi2s_be_dai_links));
+ len4 += ARRAY_SIZE(msm_mi2s_be_dai_links);
+ }
+ if (of_property_read_bool(dev->of_node,
+ "qcom,auxpcm-audio-intf")) {
+ memcpy(msm_ext_tasha_dai_links + len4,
+ msm_auxpcm_be_dai_links,
+ sizeof(msm_auxpcm_be_dai_links));
+ len4 += ARRAY_SIZE(msm_auxpcm_be_dai_links);
+ }
+ if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) {
+ dev_dbg(dev, "%s(): WCN BTFM support present\n",
+ __func__);
+ memcpy(msm_ext_tasha_dai_links + len4,
+ msm_wcn_be_dai_links,
+ sizeof(msm_wcn_be_dai_links));
+ len4 += ARRAY_SIZE(msm_wcn_be_dai_links);
+ }
+ msm_ext_dai_links = msm_ext_tasha_dai_links;
+ } else if (strnstr(card->name, "tavil", strlen(card->name))) {
+ len1 = ARRAY_SIZE(msm_ext_common_fe_dai);
+ len2 = len1 + ARRAY_SIZE(msm_ext_tavil_fe_dai);
+ len3 = len2 + ARRAY_SIZE(msm_ext_common_be_dai);
+ memcpy(msm_ext_tavil_dai_links, msm_ext_common_fe_dai,
+ sizeof(msm_ext_common_fe_dai));
+ memcpy(msm_ext_tavil_dai_links + len1,
+ msm_ext_tavil_fe_dai, sizeof(msm_ext_tavil_fe_dai));
+ memcpy(msm_ext_tavil_dai_links + len2,
+ msm_ext_common_be_dai, sizeof(msm_ext_common_be_dai));
+ memcpy(msm_ext_tavil_dai_links + len3,
+ msm_ext_tavil_be_dai, sizeof(msm_ext_tavil_be_dai));
+ len4 = len3 + ARRAY_SIZE(msm_ext_tavil_be_dai);
+ if (of_property_read_bool(dev->of_node,
+ "qcom,mi2s-audio-intf")) {
+ memcpy(msm_ext_tavil_dai_links + len4,
+ msm_mi2s_be_dai_links,
+ sizeof(msm_mi2s_be_dai_links));
+ len4 += ARRAY_SIZE(msm_mi2s_be_dai_links);
+ }
+ if (of_property_read_bool(dev->of_node,
+ "qcom,auxpcm-audio-intf")) {
+ memcpy(msm_ext_tavil_dai_links + len4,
+ msm_auxpcm_be_dai_links,
+ sizeof(msm_auxpcm_be_dai_links));
+ len4 += ARRAY_SIZE(msm_auxpcm_be_dai_links);
+ }
+ if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) {
+ dev_dbg(dev, "%s(): WCN BTFM support present\n",
+ __func__);
+ memcpy(msm_ext_tavil_dai_links + len4,
+ msm_wcn_be_dai_links,
+ sizeof(msm_wcn_be_dai_links));
+ len4 += ARRAY_SIZE(msm_wcn_be_dai_links);
+ }
+ msm_ext_dai_links = msm_ext_tavil_dai_links;
+ } else {
+ dev_err(dev, "%s: failing as no matching card name\n",
+ __func__);
+ return NULL;
+ }
+ card->dai_link = msm_ext_dai_links;
+ card->num_links = len4;
+
+ return card;
+}
+EXPORT_SYMBOL(populate_snd_card_dailinks);
diff --git a/sound/soc/msm/msmfalcon-external.c b/sound/soc/msm/msmfalcon-external.c
new file mode 100644
index 000000000000..3934c50c48a9
--- /dev/null
+++ b/sound/soc/msm/msmfalcon-external.c
@@ -0,0 +1,1765 @@
+/* Copyright (c) 2015-2016, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <sound/soc.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/q6core.h>
+#include <linux/qdsp6v2/audio_notifier.h>
+#include "qdsp6v2/msm-pcm-routing-v2.h"
+#include "msm-audio-pinctrl.h"
+#include "msmfalcon-common.h"
+#include "msmfalcon-external.h"
+#include "../codecs/wcd9335.h"
+#include "../codecs/wcd934x/wcd934x.h"
+#include "../codecs/wcd934x/wcd934x-mbhc.h"
+
+#define MSMFALCON_SPK_ON 1
+#define MSMFALCON_SPK_OFF 0
+
+#define WCD9XXX_MBHC_DEF_BUTTONS 8
+#define WCD9XXX_MBHC_DEF_RLOADS 5
+#define CODEC_EXT_CLK_RATE 9600000
+#define ADSP_STATE_READY_TIMEOUT_MS 3000
+
+#define WSA8810_NAME_1 "wsa881x.20170211"
+#define WSA8810_NAME_2 "wsa881x.20170212"
+
+static int msm_ext_spk_control = 1;
+static struct wcd_mbhc_config *wcd_mbhc_cfg_ptr;
+
+struct msm_asoc_wcd93xx_codec {
+ void* (*get_afe_config_fn)(struct snd_soc_codec *codec,
+ enum afe_config_type config_type);
+ void (*mbhc_hs_detect_exit)(struct snd_soc_codec *codec);
+};
+
+static struct msm_asoc_wcd93xx_codec msm_codec_fn;
+static struct platform_device *spdev;
+
+static bool is_initial_boot;
+
+static void *def_ext_mbhc_cal(void);
+
+enum {
+ SLIM_RX_0 = 0,
+ SLIM_RX_1,
+ SLIM_RX_2,
+ SLIM_RX_3,
+ SLIM_RX_4,
+ SLIM_RX_5,
+ SLIM_RX_6,
+ SLIM_RX_7,
+ SLIM_RX_MAX,
+};
+
+enum {
+ SLIM_TX_0 = 0,
+ SLIM_TX_1,
+ SLIM_TX_2,
+ SLIM_TX_3,
+ SLIM_TX_4,
+ SLIM_TX_5,
+ SLIM_TX_6,
+ SLIM_TX_7,
+ SLIM_TX_8,
+ SLIM_TX_MAX,
+};
+
+struct dev_config {
+ u32 sample_rate;
+ u32 bit_format;
+ u32 channels;
+};
+
+/* Default configuration of slimbus channels */
+static struct dev_config slim_rx_cfg[] = {
+ [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_RX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_RX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+};
+
+static struct dev_config slim_tx_cfg[] = {
+ [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+};
+
+static int msm_vi_feed_tx_ch = 2;
+static const char *const slim_rx_ch_text[] = {"One", "Two"};
+static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four",
+ "Five", "Six", "Seven",
+ "Eight"};
+static const char *const vi_feed_ch_text[] = {"One", "Two"};
+static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
+ "S32_LE"};
+static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16",
+ "KHZ_32", "KHZ_44P1", "KHZ_48",
+ "KHZ_88P2", "KHZ_96", "KHZ_176P4",
+ "KHZ_192", "KHZ_352P8", "KHZ_384"};
+static const char *const spk_function_text[] = {"Off", "On"};
+static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_48"};
+
+static SOC_ENUM_SINGLE_EXT_DECL(spk_func_en, spk_function_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_1_tx_chs, slim_tx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_chs, slim_rx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text);
+
+static int slim_get_sample_rate_val(int sample_rate)
+{
+ int sample_rate_val = 0;
+
+ switch (sample_rate) {
+ case SAMPLING_RATE_8KHZ:
+ sample_rate_val = 0;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ sample_rate_val = 1;
+ break;
+ case SAMPLING_RATE_32KHZ:
+ sample_rate_val = 2;
+ break;
+ case SAMPLING_RATE_44P1KHZ:
+ sample_rate_val = 3;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ sample_rate_val = 4;
+ break;
+ case SAMPLING_RATE_88P2KHZ:
+ sample_rate_val = 5;
+ break;
+ case SAMPLING_RATE_96KHZ:
+ sample_rate_val = 6;
+ break;
+ case SAMPLING_RATE_176P4KHZ:
+ sample_rate_val = 7;
+ break;
+ case SAMPLING_RATE_192KHZ:
+ sample_rate_val = 8;
+ break;
+ case SAMPLING_RATE_352P8KHZ:
+ sample_rate_val = 9;
+ break;
+ case SAMPLING_RATE_384KHZ:
+ sample_rate_val = 10;
+ break;
+ default:
+ sample_rate_val = 4;
+ break;
+ }
+ return sample_rate_val;
+}
+
+static int slim_get_sample_rate(int value)
+{
+ int sample_rate = 0;
+
+ switch (value) {
+ case 0:
+ sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ case 1:
+ sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 2:
+ sample_rate = SAMPLING_RATE_32KHZ;
+ break;
+ case 3:
+ sample_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 4:
+ sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 5:
+ sample_rate = SAMPLING_RATE_88P2KHZ;
+ break;
+ case 6:
+ sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 7:
+ sample_rate = SAMPLING_RATE_176P4KHZ;
+ break;
+ case 8:
+ sample_rate = SAMPLING_RATE_192KHZ;
+ break;
+ case 9:
+ sample_rate = SAMPLING_RATE_352P8KHZ;
+ break;
+ case 10:
+ sample_rate = SAMPLING_RATE_384KHZ;
+ break;
+ default:
+ sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+ return sample_rate;
+}
+
+static int slim_get_bit_format_val(int bit_format)
+{
+ int val = 0;
+
+ switch (bit_format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ val = 3;
+ break;
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ val = 2;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ val = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ val = 0;
+ break;
+ }
+ return val;
+}
+
+static int slim_get_bit_format(int val)
+{
+ int bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
+
+ switch (val) {
+ case 0:
+ bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ case 1:
+ bit_fmt = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 2:
+ bit_fmt = SNDRV_PCM_FORMAT_S24_3LE;
+ break;
+ case 3:
+ bit_fmt = SNDRV_PCM_FORMAT_S32_LE;
+ break;
+ default:
+ bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ return bit_fmt;
+}
+
+static int slim_get_port_idx(struct snd_kcontrol *kcontrol)
+{
+ int port_id = 0;
+
+ if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX")))
+ port_id = SLIM_RX_0;
+ else if (strnstr(kcontrol->id.name, "SLIM_2_RX", sizeof("SLIM_2_RX")))
+ port_id = SLIM_RX_2;
+ else if (strnstr(kcontrol->id.name, "SLIM_5_RX", sizeof("SLIM_5_RX")))
+ port_id = SLIM_RX_5;
+ else if (strnstr(kcontrol->id.name, "SLIM_6_RX", sizeof("SLIM_6_RX")))
+ port_id = SLIM_RX_6;
+ else if (strnstr(kcontrol->id.name, "SLIM_0_TX", sizeof("SLIM_0_TX")))
+ port_id = SLIM_TX_0;
+ else if (strnstr(kcontrol->id.name, "SLIM_1_TX", sizeof("SLIM_1_TX")))
+ port_id = SLIM_TX_1;
+ else {
+ pr_err("%s: unsupported channel: %s",
+ __func__, kcontrol->id.name);
+ return -EINVAL;
+ }
+
+ return port_id;
+}
+
+static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ /*
+ * Slimbus_7_Rx/Tx sample rate values should always be in sync (same)
+ * when used for BT_SCO use case. Return either Rx or Tx sample rate
+ * value.
+ */
+ switch (slim_rx_cfg[SLIM_RX_7].sample_rate) {
+ case SAMPLING_RATE_48KHZ:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SAMPLING_RATE_8KHZ:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: sample rate = %d", __func__,
+ slim_rx_cfg[SLIM_RX_7].sample_rate);
+
+ return 0;
+}
+
+static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ;
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 2:
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ;
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 0:
+ default:
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ;
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ }
+ pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n",
+ __func__,
+ slim_rx_cfg[SLIM_RX_7].sample_rate,
+ slim_tx_cfg[SLIM_TX_7].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ ucontrol->value.enumerated.item[0] =
+ slim_get_sample_rate_val(slim_rx_cfg[ch_num].sample_rate);
+
+ pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__,
+ ch_num, slim_rx_cfg[ch_num].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ slim_rx_cfg[ch_num].sample_rate =
+ slim_get_sample_rate(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__,
+ ch_num, slim_rx_cfg[ch_num].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ ucontrol->value.enumerated.item[0] =
+ slim_get_sample_rate_val(slim_tx_cfg[ch_num].sample_rate);
+
+ pr_debug("%s: slim[%d]_tx_sample_rate = %d, item = %d\n", __func__,
+ ch_num, slim_tx_cfg[ch_num].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int sample_rate = 0;
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ sample_rate = slim_get_sample_rate(ucontrol->value.enumerated.item[0]);
+ if (sample_rate == SAMPLING_RATE_44P1KHZ) {
+ pr_err("%s: Unsupported sample rate %d: for Tx path\n",
+ __func__, sample_rate);
+ return -EINVAL;
+ }
+ slim_tx_cfg[ch_num].sample_rate = sample_rate;
+
+ pr_debug("%s: slim[%d]_tx_sample_rate = %d, value = %d\n", __func__,
+ ch_num, slim_tx_cfg[ch_num].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_rx_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ ucontrol->value.enumerated.item[0] =
+ slim_get_bit_format_val(slim_rx_cfg[ch_num].bit_format);
+
+ pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n",
+ __func__, ch_num, slim_rx_cfg[ch_num].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_rx_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ slim_rx_cfg[ch_num].bit_format =
+ slim_get_bit_format(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n",
+ __func__, ch_num, slim_rx_cfg[ch_num].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_tx_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ ucontrol->value.enumerated.item[0] =
+ slim_get_bit_format_val(slim_tx_cfg[ch_num].bit_format);
+
+ pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n",
+ __func__, ch_num, slim_tx_cfg[ch_num].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_tx_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ slim_tx_cfg[ch_num].bit_format =
+ slim_get_bit_format(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n",
+ __func__, ch_num, slim_tx_cfg[ch_num].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int msm_slim_rx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__,
+ ch_num, slim_rx_cfg[ch_num].channels);
+ ucontrol->value.enumerated.item[0] = slim_rx_cfg[ch_num].channels - 1;
+
+ return 0;
+}
+
+static int msm_slim_rx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ slim_rx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1;
+ pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__,
+ ch_num, slim_rx_cfg[ch_num].channels);
+
+ return 1;
+}
+
+static int msm_slim_tx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__,
+ ch_num, slim_tx_cfg[ch_num].channels);
+ ucontrol->value.enumerated.item[0] = slim_tx_cfg[ch_num].channels - 1;
+
+ return 0;
+}
+
+static int msm_slim_tx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ slim_tx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1;
+ pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__,
+ ch_num, slim_tx_cfg[ch_num].channels);
+
+ return 1;
+}
+
+static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1;
+ pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__,
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1;
+
+ pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch);
+ return 1;
+}
+
+static void *def_ext_mbhc_cal(void)
+{
+ void *tavil_wcd_cal;
+ struct wcd_mbhc_btn_detect_cfg *btn_cfg;
+ u16 *btn_high;
+
+ tavil_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS,
+ WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL);
+ if (!tavil_wcd_cal)
+ return NULL;
+
+#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tavil_wcd_cal)->X) = (Y))
+ S(v_hs_max, 1600);
+#undef S
+#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal)->X) = (Y))
+ S(num_btn, WCD_MBHC_DEF_BUTTONS);
+#undef S
+
+ btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal);
+ btn_high = ((void *)&btn_cfg->_v_btn_low) +
+ (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn);
+
+ btn_high[0] = 75;
+ btn_high[1] = 150;
+ btn_high[2] = 237;
+ btn_high[3] = 500;
+ btn_high[4] = 500;
+ btn_high[5] = 500;
+ btn_high[6] = 500;
+ btn_high[7] = 500;
+
+ return tavil_wcd_cal;
+}
+
+static inline int param_is_mask(int p)
+{
+ return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
+ (p <= SNDRV_PCM_HW_PARAM_LAST_MASK);
+}
+
+static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, int n)
+{
+ return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
+}
+
+
+static void msm_ext_control(struct snd_soc_codec *codec)
+{
+ struct snd_soc_dapm_context *dapm =
+ snd_soc_codec_get_dapm(codec);
+
+ pr_debug("%s: msm_ext_spk_control = %d", __func__, msm_ext_spk_control);
+ if (msm_ext_spk_control == MSMFALCON_SPK_ON) {
+ snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp");
+ snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp");
+ } else {
+ snd_soc_dapm_disable_pin(dapm, "Lineout_1 amp");
+ snd_soc_dapm_disable_pin(dapm, "Lineout_3 amp");
+ }
+ snd_soc_dapm_sync(dapm);
+}
+
+static int msm_ext_get_spk(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_ext_spk_control = %d\n",
+ __func__, msm_ext_spk_control);
+ ucontrol->value.integer.value[0] = msm_ext_spk_control;
+ return 0;
+}
+
+static int msm_ext_set_spk(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+
+ pr_debug("%s()\n", __func__);
+ if (msm_ext_spk_control == ucontrol->value.integer.value[0])
+ return 0;
+
+ msm_ext_spk_control = ucontrol->value.integer.value[0];
+ msm_ext_control(codec);
+ return 1;
+}
+
+
+int msm_ext_enable_codec_mclk(struct snd_soc_codec *codec, int enable,
+ bool dapm)
+{
+ int ret;
+
+ pr_debug("%s: enable = %d\n", __func__, enable);
+
+ if (!strcmp(dev_name(codec->dev), "tasha_codec"))
+ ret = tasha_cdc_mclk_enable(codec, enable, dapm);
+ else if (!strcmp(dev_name(codec->dev), "tavil_codec"))
+ ret = tavil_cdc_mclk_enable(codec, enable);
+ else {
+ dev_err(codec->dev, "%s: unknown codec to enable ext clk\n",
+ __func__);
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+static const struct snd_kcontrol_new msm_snd_controls[] = {
+ SOC_ENUM_EXT("Speaker Function", spk_func_en, msm_ext_get_spk,
+ msm_ext_set_spk),
+ SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs,
+ msm_slim_rx_ch_get, msm_slim_rx_ch_put),
+ SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs,
+ msm_slim_rx_ch_get, msm_slim_rx_ch_put),
+ SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs,
+ msm_slim_tx_ch_get, msm_slim_tx_ch_put),
+ SOC_ENUM_EXT("SLIM_1_TX Channels", slim_1_tx_chs,
+ msm_slim_tx_ch_get, msm_slim_tx_ch_put),
+ SOC_ENUM_EXT("SLIM_5_RX Channels", slim_5_rx_chs,
+ msm_slim_rx_ch_get, msm_slim_rx_ch_put),
+ SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs,
+ msm_slim_rx_ch_get, msm_slim_rx_ch_put),
+ SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs,
+ msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put),
+ SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format,
+ slim_rx_bit_format_get, slim_rx_bit_format_put),
+ SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format,
+ slim_rx_bit_format_get, slim_rx_bit_format_put),
+ SOC_ENUM_EXT("SLIM_6_RX Format", slim_6_rx_format,
+ slim_rx_bit_format_get, slim_rx_bit_format_put),
+ SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format,
+ slim_tx_bit_format_get, slim_tx_bit_format_put),
+ SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate,
+ slim_rx_sample_rate_get, slim_rx_sample_rate_put),
+ SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate,
+ slim_rx_sample_rate_get, slim_rx_sample_rate_put),
+ SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate,
+ slim_tx_sample_rate_get, slim_tx_sample_rate_put),
+ SOC_ENUM_EXT("SLIM_5_RX SampleRate", slim_5_rx_sample_rate,
+ slim_rx_sample_rate_get, slim_rx_sample_rate_put),
+ SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate,
+ slim_rx_sample_rate_get, slim_rx_sample_rate_put),
+ SOC_ENUM_EXT("BT SampleRate", bt_sample_rate,
+ msm_bt_sample_rate_get,
+ msm_bt_sample_rate_put),
+};
+
+static int msm_slim_get_ch_from_beid(int32_t be_id)
+{
+ int ch_id = 0;
+
+ switch (be_id) {
+ case MSM_BACKEND_DAI_SLIMBUS_0_RX:
+ ch_id = SLIM_RX_0;
+ break;
+ case MSM_BACKEND_DAI_SLIMBUS_1_RX:
+ ch_id = SLIM_RX_1;
+ break;
+ case MSM_BACKEND_DAI_SLIMBUS_2_RX:
+ ch_id = SLIM_RX_2;
+ break;
+ case MSM_BACKEND_DAI_SLIMBUS_3_RX:
+ ch_id = SLIM_RX_3;
+ break;
+ case MSM_BACKEND_DAI_SLIMBUS_4_RX:
+ ch_id = SLIM_RX_4;
+ break;
+ case MSM_BACKEND_DAI_SLIMBUS_6_RX:
+ ch_id = SLIM_RX_6;
+ break;
+ case MSM_BACKEND_DAI_SLIMBUS_0_TX:
+ ch_id = SLIM_TX_0;
+ break;
+ case MSM_BACKEND_DAI_SLIMBUS_3_TX:
+ ch_id = SLIM_TX_3;
+ break;
+ default:
+ ch_id = SLIM_RX_0;
+ break;
+ }
+
+ return ch_id;
+}
+
+static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned bit)
+{
+ if (bit >= SNDRV_MASK_MAX)
+ return;
+ if (param_is_mask(n)) {
+ struct snd_mask *m = param_to_mask(p, n);
+
+ m->bits[0] = 0;
+ m->bits[1] = 0;
+ m->bits[bit >> 5] |= (1 << (bit & 31));
+ }
+}
+
+/**
+ * msm_ext_be_hw_params_fixup - updates settings of ALSA BE hw params.
+ *
+ * @rtd: runtime dailink instance
+ * @params: HW params of associated backend dailink.
+ *
+ * Returns 0 on success or rc on failure.
+ */
+int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+ int rc = 0;
+ int idx;
+ void *config = NULL;
+ struct snd_soc_codec *codec = rtd->codec;
+
+ pr_debug("%s: format = %d, rate = %d\n",
+ __func__, params_format(params), params_rate(params));
+
+ switch (dai_link->be_id) {
+ case MSM_BACKEND_DAI_SLIMBUS_0_RX:
+ case MSM_BACKEND_DAI_SLIMBUS_1_RX:
+ case MSM_BACKEND_DAI_SLIMBUS_2_RX:
+ case MSM_BACKEND_DAI_SLIMBUS_3_RX:
+ case MSM_BACKEND_DAI_SLIMBUS_4_RX:
+ case MSM_BACKEND_DAI_SLIMBUS_6_RX:
+ idx = msm_slim_get_ch_from_beid(dai_link->be_id);
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ slim_rx_cfg[idx].bit_format);
+ rate->min = rate->max = slim_rx_cfg[idx].sample_rate;
+ channels->min = channels->max = slim_rx_cfg[idx].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_0_TX:
+ case MSM_BACKEND_DAI_SLIMBUS_3_TX:
+ idx = msm_slim_get_ch_from_beid(dai_link->be_id);
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ slim_tx_cfg[idx].bit_format);
+ rate->min = rate->max = slim_tx_cfg[idx].sample_rate;
+ channels->min = channels->max = slim_tx_cfg[idx].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_1_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ slim_tx_cfg[1].bit_format);
+ rate->min = rate->max = slim_tx_cfg[1].sample_rate;
+ channels->min = channels->max = slim_tx_cfg[1].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_4_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ SNDRV_PCM_FORMAT_S32_LE);
+ rate->min = rate->max = SAMPLING_RATE_8KHZ;
+ channels->min = channels->max = msm_vi_feed_tx_ch;
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_5_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ slim_rx_cfg[5].bit_format);
+ rate->min = rate->max = slim_rx_cfg[5].sample_rate;
+ channels->min = channels->max = slim_rx_cfg[5].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_5_TX:
+ rate->min = rate->max = SAMPLING_RATE_16KHZ;
+ channels->min = channels->max = 1;
+
+ config = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_SLIMBUS_SLAVE_PORT_CONFIG);
+ if (config) {
+ rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG,
+ config, SLIMBUS_5_TX);
+ if (rc)
+ pr_err("%s: Failed to set slimbus slave port config %d\n",
+ __func__, rc);
+ }
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_7_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ slim_rx_cfg[SLIM_RX_7].bit_format);
+ rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate;
+ channels->min = channels->max =
+ slim_rx_cfg[SLIM_RX_7].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_7_TX:
+ rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate;
+ channels->min = channels->max =
+ slim_tx_cfg[SLIM_TX_7].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_8_TX:
+ rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate;
+ channels->min = channels->max =
+ slim_tx_cfg[SLIM_TX_8].channels;
+ break;
+
+ default:
+ rate->min = rate->max = SAMPLING_RATE_48KHZ;
+ break;
+ }
+ return rc;
+}
+EXPORT_SYMBOL(msm_ext_be_hw_params_fixup);
+
+/**
+ * msm_snd_hw_params - hw params ops of backend dailink.
+ *
+ * @substream: PCM stream of associated backend dailink.
+ * @params: HW params of associated backend dailink.
+ *
+ * Returns 0 on success or ret on failure.
+ */
+int msm_snd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+
+ int ret = 0;
+ u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
+ u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
+ u32 user_set_tx_ch = 0;
+ u32 rx_ch_count;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map, err:%d\n",
+ __func__, ret);
+ goto err_ch_map;
+ }
+ if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_5_RX) {
+ pr_debug("%s: rx_5_ch=%d\n", __func__,
+ slim_rx_cfg[5].channels);
+ rx_ch_count = slim_rx_cfg[5].channels;
+ } else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_2_RX) {
+ pr_debug("%s: rx_2_ch=%d\n", __func__,
+ slim_rx_cfg[2].channels);
+ rx_ch_count = slim_rx_cfg[2].channels;
+ } else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_6_RX) {
+ pr_debug("%s: rx_6_ch=%d\n", __func__,
+ slim_rx_cfg[6].channels);
+ rx_ch_count = slim_rx_cfg[6].channels;
+ } else {
+ pr_debug("%s: rx_0_ch=%d\n", __func__,
+ slim_rx_cfg[0].channels);
+ rx_ch_count = slim_rx_cfg[0].channels;
+ }
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
+ rx_ch_count, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to set cpu chan map, err:%d\n",
+ __func__, ret);
+ goto err_ch_map;
+ }
+ } else {
+ pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__,
+ codec_dai->name, codec_dai->id, user_set_tx_ch);
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map\n, err:%d\n",
+ __func__, ret);
+ goto err_ch_map;
+ }
+ /* For <codec>_tx1 case */
+ if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_0_TX)
+ user_set_tx_ch = slim_tx_cfg[0].channels;
+ /* For <codec>_tx3 case */
+ else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_1_TX)
+ user_set_tx_ch = slim_tx_cfg[1].channels;
+ else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_4_TX)
+ user_set_tx_ch = msm_vi_feed_tx_ch;
+ else
+ user_set_tx_ch = tx_ch_cnt;
+
+ pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), be_id (%d)\n",
+ __func__, slim_tx_cfg[0].channels, user_set_tx_ch,
+ tx_ch_cnt, dai_link->be_id);
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ user_set_tx_ch, tx_ch, 0, 0);
+ if (ret < 0)
+ pr_err("%s: failed to set cpu chan map, err:%d\n",
+ __func__, ret);
+ }
+
+err_ch_map:
+ return ret;
+}
+EXPORT_SYMBOL(msm_snd_hw_params);
+
+/**
+ * msm_ext_slimbus_2_hw_params - hw params ops of slimbus_2 BE.
+ *
+ * @substream: PCM stream of associated backend dailink.
+ * @params: HW params of associated backend dailink.
+ *
+ * Returns 0 on success or ret on failure.
+ */
+int msm_ext_slimbus_2_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+ unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
+ unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0;
+ unsigned int num_tx_ch = 0;
+ unsigned int num_rx_ch = 0;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ num_rx_ch = params_channels(params);
+ pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__,
+ codec_dai->name, codec_dai->id, num_rx_ch);
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
+ num_rx_ch, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to set cpu chan map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ } else {
+ num_tx_ch = params_channels(params);
+ pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__,
+ codec_dai->name, codec_dai->id, num_tx_ch);
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ num_tx_ch, tx_ch, 0, 0);
+ if (ret < 0) {
+ pr_err("%s: failed to set cpu chan map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ }
+end:
+ return ret;
+}
+EXPORT_SYMBOL(msm_ext_slimbus_2_hw_params);
+
+/**
+ * msm_snd_cpe_hw_params - hw params ops of CPE backend.
+ *
+ * @substream: PCM stream of associated backend dailink.
+ * @params: HW params of associated backend dailink.
+ *
+ * Returns 0 on success or ret on failure.
+ */
+int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+ int ret = 0;
+ u32 tx_ch[SLIM_MAX_TX_PORTS];
+ u32 tx_ch_cnt = 0;
+
+ if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) {
+ pr_err("%s: Invalid stream type %d\n",
+ __func__, substream->stream);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ pr_debug("%s: %s_tx_dai_id_%d\n", __func__,
+ codec_dai->name, codec_dai->id);
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, NULL, NULL);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map\n, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ pr_debug("%s: tx_ch_cnt(%d) be_id %d\n",
+ __func__, tx_ch_cnt, dai_link->be_id);
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ tx_ch_cnt, tx_ch, 0, 0);
+ if (ret < 0) {
+ pr_err("%s: failed to set cpu chan map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+end:
+ return ret;
+}
+EXPORT_SYMBOL(msm_snd_cpe_hw_params);
+
+static int msm_afe_set_config(struct snd_soc_codec *codec)
+{
+ int rc;
+ void *config_data;
+
+ pr_debug("%s: enter\n", __func__);
+
+ if (!msm_codec_fn.get_afe_config_fn) {
+ dev_err(codec->dev, "%s: codec get afe config not init'ed\n",
+ __func__);
+ return -EINVAL;
+ }
+ config_data = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_CDC_REGISTERS_CONFIG);
+ if (config_data) {
+ rc = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0);
+ if (rc) {
+ pr_err("%s: Failed to set codec registers config %d\n",
+ __func__, rc);
+ return rc;
+ }
+ }
+
+ config_data = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_CDC_REGISTER_PAGE_CONFIG);
+ if (config_data) {
+ rc = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data,
+ 0);
+ if (rc)
+ pr_err("%s: Failed to set cdc register page config\n",
+ __func__);
+ }
+
+ config_data = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_SLIMBUS_SLAVE_CONFIG);
+ if (config_data) {
+ rc = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0);
+ if (rc) {
+ pr_err("%s: Failed to set slimbus slave config %d\n",
+ __func__, rc);
+ return rc;
+ }
+ }
+
+ config_data = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_AANC_VERSION);
+ if (config_data) {
+ rc = afe_set_config(AFE_AANC_VERSION, config_data, 0);
+ if (rc) {
+ pr_err("%s: Failed to set AANC version %d\n",
+ __func__, rc);
+ return rc;
+ }
+ }
+
+ config_data = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_CDC_CLIP_REGISTERS_CONFIG);
+ if (config_data) {
+ rc = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG,
+ config_data, 0);
+ if (rc) {
+ pr_err("%s: Failed to set clip registers %d\n",
+ __func__, rc);
+ return rc;
+ }
+ }
+
+ config_data = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_CLIP_BANK_SEL);
+ if (config_data) {
+ rc = afe_set_config(AFE_CLIP_BANK_SEL,
+ config_data, 0);
+ if (rc) {
+ pr_err("%s: Failed to set AFE bank selection %d\n",
+ __func__, rc);
+ return rc;
+ }
+ }
+
+ config_data = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_CDC_REGISTER_PAGE_CONFIG);
+ if (config_data) {
+ rc = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data,
+ 0);
+ if (rc)
+ pr_err("%s: Failed to set cdc register page config\n",
+ __func__);
+ }
+
+ return 0;
+}
+
+static void msm_afe_clear_config(void)
+{
+ afe_clear_config(AFE_CDC_REGISTERS_CONFIG);
+ afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG);
+}
+
+static int msm_adsp_power_up_config(struct snd_soc_codec *codec)
+{
+ int ret = 0;
+ unsigned long timeout;
+ int adsp_ready = 0;
+
+ timeout = jiffies +
+ msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS);
+
+ do {
+ if (q6core_is_adsp_ready()) {
+ pr_debug("%s: ADSP Audio is ready\n", __func__);
+ adsp_ready = 1;
+ break;
+ }
+ /*
+ * ADSP will be coming up after subsystem restart and
+ * it might not be fully up when the control reaches
+ * here. So, wait for 50msec before checking ADSP state
+ */
+ msleep(50);
+ } while (time_after(timeout, jiffies));
+
+ if (!adsp_ready) {
+ pr_err("%s: timed out waiting for ADSP Audio\n", __func__);
+ ret = -ETIMEDOUT;
+ goto err_fail;
+ }
+
+ ret = msm_afe_set_config(codec);
+ if (ret)
+ pr_err("%s: Failed to set AFE config. err %d\n",
+ __func__, ret);
+
+ return 0;
+
+err_fail:
+ return ret;
+}
+
+static int msmfalcon_notifier_service_cb(struct notifier_block *this,
+ unsigned long opcode, void *ptr)
+{
+ int ret;
+ struct snd_soc_card *card = NULL;
+ const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
+ struct snd_soc_pcm_runtime *rtd;
+ struct snd_soc_codec *codec;
+
+ pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode);
+
+ switch (opcode) {
+ case AUDIO_NOTIFIER_SERVICE_DOWN:
+ /*
+ * Use flag to ignore initial boot notifications
+ * On initial boot msm_adsp_power_up_config is
+ * called on init. There is no need to clear
+ * and set the config again on initial boot.
+ */
+ if (is_initial_boot)
+ break;
+ msm_afe_clear_config();
+ break;
+ case AUDIO_NOTIFIER_SERVICE_UP:
+ if (is_initial_boot) {
+ is_initial_boot = false;
+ break;
+ }
+ if (!spdev)
+ return -EINVAL;
+
+ card = platform_get_drvdata(spdev);
+ rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
+ if (!rtd) {
+ dev_err(card->dev,
+ "%s: snd_soc_get_pcm_runtime for %s failed!\n",
+ __func__, be_dl_name);
+ ret = -EINVAL;
+ goto done;
+ }
+ codec = rtd->codec;
+
+ ret = msm_adsp_power_up_config(codec);
+ if (ret < 0) {
+ dev_err(card->dev,
+ "%s: msm_adsp_power_up_config failed ret = %d!\n",
+ __func__, ret);
+ goto done;
+ }
+ break;
+ default:
+ break;
+ }
+done:
+ return NOTIFY_OK;
+}
+
+static struct notifier_block service_nb = {
+ .notifier_call = msmfalcon_notifier_service_cb,
+ .priority = -INT_MAX,
+};
+
+static int msm_config_hph_en0_gpio(struct snd_soc_codec *codec, bool high)
+{
+ struct snd_soc_card *card = codec->component.card;
+ struct msm_asoc_mach_data *pdata;
+ int val;
+
+ if (!card)
+ return 0;
+
+ pdata = snd_soc_card_get_drvdata(card);
+ if (!pdata || !gpio_is_valid(pdata->hph_en0_gpio))
+ return 0;
+
+ val = gpio_get_value_cansleep(pdata->hph_en0_gpio);
+ if ((!!val) == high)
+ return 0;
+
+ gpio_direction_output(pdata->hph_en0_gpio, (int)high);
+
+ return 1;
+}
+
+static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec,
+ int enable, bool dapm)
+{
+ int ret = 0;
+
+ if (!strcmp(dev_name(codec->dev), "tasha_codec"))
+ ret = tasha_cdc_mclk_tx_enable(codec, enable, dapm);
+ else {
+ dev_err(codec->dev, "%s: unknown codec to enable ext clk\n",
+ __func__);
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+static int msm_ext_mclk_tx_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ pr_debug("%s: event = %d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ return msm_snd_enable_codec_ext_tx_clk(codec, 1, true);
+ case SND_SOC_DAPM_POST_PMD:
+ return msm_snd_enable_codec_ext_tx_clk(codec, 0, true);
+ }
+ return 0;
+}
+
+static int msm_ext_mclk_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ pr_debug("%s: event = %d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ return msm_ext_enable_codec_mclk(codec, 1, true);
+ case SND_SOC_DAPM_POST_PMD:
+ return msm_ext_enable_codec_mclk(codec, 0, true);
+ }
+ return 0;
+}
+
+static int msm_ext_prepare_hifi(struct msm_asoc_mach_data *pdata)
+{
+ int ret = 0;
+
+ if (gpio_is_valid(pdata->hph_en1_gpio)) {
+ pr_debug("%s: hph_en1_gpio request %d\n", __func__,
+ pdata->hph_en1_gpio);
+ ret = gpio_request(pdata->hph_en1_gpio, "hph_en1_gpio");
+ if (ret) {
+ pr_err("%s: hph_en1_gpio request failed, ret:%d\n",
+ __func__, ret);
+ goto err;
+ }
+ }
+ if (gpio_is_valid(pdata->hph_en0_gpio)) {
+ pr_debug("%s: hph_en0_gpio request %d\n", __func__,
+ pdata->hph_en0_gpio);
+ ret = gpio_request(pdata->hph_en0_gpio, "hph_en0_gpio");
+ if (ret)
+ pr_err("%s: hph_en0_gpio request failed, ret:%d\n",
+ __func__, ret);
+ }
+
+err:
+ return ret;
+}
+
+static const struct snd_soc_dapm_widget msm_dapm_widgets[] = {
+
+ SND_SOC_DAPM_SUPPLY_S("MCLK", -1, SND_SOC_NOPM, 0, 0,
+ msm_ext_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("MCLK TX", -1, SND_SOC_NOPM, 0, 0,
+ msm_ext_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SPK("Lineout_1 amp", NULL),
+ SND_SOC_DAPM_SPK("Lineout_3 amp", NULL),
+ SND_SOC_DAPM_SPK("Lineout_2 amp", NULL),
+ SND_SOC_DAPM_SPK("Lineout_4 amp", NULL),
+ SND_SOC_DAPM_MIC("Handset Mic", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Secondary Mic", NULL),
+ SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Analog Mic4", NULL),
+ SND_SOC_DAPM_MIC("Analog Mic6", NULL),
+ SND_SOC_DAPM_MIC("Analog Mic7", NULL),
+ SND_SOC_DAPM_MIC("Analog Mic8", NULL),
+
+ SND_SOC_DAPM_MIC("Digital Mic0", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic1", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic2", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic3", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic4", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic5", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic6", NULL),
+};
+
+static struct snd_soc_dapm_route wcd_audio_paths_tasha[] = {
+ {"MIC BIAS1", NULL, "MCLK TX"},
+ {"MIC BIAS2", NULL, "MCLK TX"},
+ {"MIC BIAS3", NULL, "MCLK TX"},
+ {"MIC BIAS4", NULL, "MCLK TX"},
+};
+
+static struct snd_soc_dapm_route wcd_audio_paths[] = {
+ {"MIC BIAS1", NULL, "MCLK"},
+ {"MIC BIAS2", NULL, "MCLK"},
+ {"MIC BIAS3", NULL, "MCLK"},
+ {"MIC BIAS4", NULL, "MCLK"},
+};
+
+/**
+ * msm_audrx_init - Audio init function of sound card instantiate.
+ *
+ * @rtd: runtime dailink instance
+ *
+ * Returns 0 on success or ret on failure.
+ */
+int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
+{
+ int ret;
+ void *config_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm =
+ snd_soc_codec_get_dapm(codec);
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_pcm_runtime *rtd_aux = rtd->card->rtd_aux;
+ struct snd_card *card;
+ struct snd_info_entry *entry;
+ struct msm_asoc_mach_data *pdata =
+ snd_soc_card_get_drvdata(rtd->card);
+
+ /* Codec SLIMBUS configuration
+ * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13
+ * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13
+ * TX14, TX15, TX16
+ */
+ unsigned int rx_ch[TASHA_RX_MAX] = {144, 145, 146, 147, 148, 149, 150,
+ 151, 152, 153, 154, 155, 156};
+ unsigned int tx_ch[TASHA_TX_MAX] = {128, 129, 130, 131, 132, 133,
+ 134, 135, 136, 137, 138, 139,
+ 140, 141, 142, 143};
+
+ pr_debug("%s: dev_name%s\n", __func__, dev_name(cpu_dai->dev));
+
+ rtd->pmdown_time = 0;
+
+ ret = snd_soc_add_codec_controls(codec, msm_snd_controls,
+ ARRAY_SIZE(msm_snd_controls));
+ if (ret < 0) {
+ pr_err("%s: add_codec_controls failed: %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ snd_soc_dapm_new_controls(dapm, msm_dapm_widgets,
+ ARRAY_SIZE(msm_dapm_widgets));
+
+ if (!strcmp(dev_name(codec_dai->dev), "tasha_codec"))
+ snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tasha,
+ ARRAY_SIZE(wcd_audio_paths_tasha));
+ else
+ snd_soc_dapm_add_routes(dapm, wcd_audio_paths,
+ ARRAY_SIZE(wcd_audio_paths));
+
+ snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp");
+ snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp");
+ snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp");
+ snd_soc_dapm_enable_pin(dapm, "Lineout_4 amp");
+
+ snd_soc_dapm_ignore_suspend(dapm, "MADINPUT");
+ snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT");
+ snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Secondary Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Lineout_1 amp");
+ snd_soc_dapm_ignore_suspend(dapm, "Lineout_3 amp");
+ snd_soc_dapm_ignore_suspend(dapm, "Lineout_2 amp");
+ snd_soc_dapm_ignore_suspend(dapm, "Lineout_4 amp");
+ snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5");
+ snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4");
+ snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6");
+ snd_soc_dapm_ignore_suspend(dapm, "Analog Mic7");
+ snd_soc_dapm_ignore_suspend(dapm, "Analog Mic8");
+
+ snd_soc_dapm_ignore_suspend(dapm, "EAR");
+ snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1");
+ snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2");
+ snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3");
+ snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4");
+ snd_soc_dapm_ignore_suspend(dapm, "AMIC1");
+ snd_soc_dapm_ignore_suspend(dapm, "AMIC2");
+ snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
+ snd_soc_dapm_ignore_suspend(dapm, "AMIC4");
+ snd_soc_dapm_ignore_suspend(dapm, "AMIC5");
+ snd_soc_dapm_ignore_suspend(dapm, "AMIC6");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC0");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC1");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC2");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC3");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC4");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC5");
+ snd_soc_dapm_ignore_suspend(dapm, "ANC EAR");
+ snd_soc_dapm_ignore_suspend(dapm, "ANC HEADPHONE");
+ snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT");
+ snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT");
+ snd_soc_dapm_ignore_suspend(dapm, "HPHL");
+ snd_soc_dapm_ignore_suspend(dapm, "HPHR");
+ 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");
+ snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI");
+ snd_soc_dapm_ignore_suspend(dapm, "VIINPUT");
+
+ snd_soc_dapm_sync(dapm);
+ snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
+ tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
+
+ if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) {
+ msm_codec_fn.get_afe_config_fn = tavil_get_afe_config;
+ } else {
+ msm_codec_fn.get_afe_config_fn = tasha_get_afe_config;
+ msm_codec_fn.mbhc_hs_detect_exit = tasha_mbhc_hs_detect_exit;
+ }
+
+ ret = msm_adsp_power_up_config(codec);
+ if (ret) {
+ pr_err("%s: Failed to set AFE config %d\n", __func__, ret);
+ goto err_afe_cfg;
+ }
+
+ config_data = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_AANC_VERSION);
+ if (config_data) {
+ ret = afe_set_config(AFE_AANC_VERSION, config_data, 0);
+ if (ret) {
+ pr_err("%s: Failed to set aanc version %d\n",
+ __func__, ret);
+ goto err_afe_cfg;
+ }
+ }
+
+ if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) {
+ config_data = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_CDC_CLIP_REGISTERS_CONFIG);
+ if (config_data) {
+ ret = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG,
+ config_data, 0);
+ if (ret) {
+ pr_err("%s: Failed to set clip registers %d\n",
+ __func__, ret);
+ goto err_afe_cfg;
+ }
+ }
+ config_data = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_CLIP_BANK_SEL);
+ if (config_data) {
+ ret = afe_set_config(AFE_CLIP_BANK_SEL, config_data, 0);
+ if (ret) {
+ pr_err("%s: Failed to set AFE bank selection %d\n",
+ __func__, ret);
+ goto err_afe_cfg;
+ }
+ }
+ }
+
+ /*
+ * Send speaker configuration only for WSA8810.
+ * Defalut configuration is for WSA8815.
+ */
+ if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) {
+ if (rtd_aux && rtd_aux->component)
+ if (!strcmp(rtd_aux->component->name, WSA8810_NAME_1) ||
+ !strcmp(rtd_aux->component->name, WSA8810_NAME_2)) {
+ tavil_set_spkr_mode(rtd->codec, SPKR_MODE_1);
+ tavil_set_spkr_gain_offset(rtd->codec,
+ RX_GAIN_OFFSET_M1P5_DB);
+ }
+ card = rtd->card->snd_card;
+ entry = snd_register_module_info(card->module, "codecs",
+ card->proc_root);
+ if (!entry) {
+ pr_debug("%s: Cannot create codecs module entry\n",
+ __func__);
+ pdata->codec_root = NULL;
+ goto done;
+ }
+ pdata->codec_root = entry;
+ tavil_codec_info_create_codec_entry(pdata->codec_root, codec);
+ } else {
+ if (rtd_aux && rtd_aux->component)
+ if (!strcmp(rtd_aux->component->name, WSA8810_NAME_1) ||
+ !strcmp(rtd_aux->component->name, WSA8810_NAME_2)) {
+ tasha_set_spkr_mode(rtd->codec, SPKR_MODE_1);
+ tasha_set_spkr_gain_offset(rtd->codec,
+ RX_GAIN_OFFSET_M1P5_DB);
+ }
+ card = rtd->card->snd_card;
+ entry = snd_register_module_info(card->module, "codecs",
+ card->proc_root);
+ if (!entry) {
+ pr_debug("%s: Cannot create codecs module entry\n",
+ __func__);
+ ret = 0;
+ goto err_snd_module;
+ }
+ pdata->codec_root = entry;
+ tasha_codec_info_create_codec_entry(pdata->codec_root, codec);
+ tasha_mbhc_zdet_gpio_ctrl(msm_config_hph_en0_gpio, rtd->codec);
+ }
+
+ wcd_mbhc_cfg_ptr->calibration = def_ext_mbhc_cal();
+ if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) {
+ if (wcd_mbhc_cfg_ptr->calibration) {
+ pdata->codec = codec;
+ ret = tavil_mbhc_hs_detect(codec, wcd_mbhc_cfg_ptr);
+ if (ret < 0)
+ pr_err("%s: Failed to intialise mbhc %d\n",
+ __func__, ret);
+ } else {
+ pr_err("%s: wcd_mbhc_cfg calibration is NULL\n",
+ __func__);
+ ret = -ENOMEM;
+ goto err_mbhc_cal;
+ }
+ } else {
+ if (wcd_mbhc_cfg_ptr->calibration) {
+ pdata->codec = codec;
+ ret = tasha_mbhc_hs_detect(codec, wcd_mbhc_cfg_ptr);
+ if (ret < 0)
+ pr_err("%s: Failed to intialise mbhc %d\n",
+ __func__, ret);
+ } else {
+ pr_err("%s: wcd_mbhc_cfg calibration is NULL\n",
+ __func__);
+ ret = -ENOMEM;
+ goto err_mbhc_cal;
+ }
+
+ }
+done:
+ return 0;
+
+err_snd_module:
+err_afe_cfg:
+err_mbhc_cal:
+ return ret;
+}
+EXPORT_SYMBOL(msm_audrx_init);
+
+/**
+ * msm_ext_register_audio_notifier - register SSR notifier.
+ */
+void msm_ext_register_audio_notifier(void)
+{
+ int ret;
+
+ ret = audio_notifier_register("msmfalcon", AUDIO_NOTIFIER_ADSP_DOMAIN,
+ &service_nb);
+ if (ret < 0)
+ pr_err("%s: Audio notifier register failed ret = %d\n",
+ __func__, ret);
+}
+EXPORT_SYMBOL(msm_ext_register_audio_notifier);
+
+/**
+ * msm_ext_cdc_init - external codec machine specific init.
+ *
+ * @pdev: platform device handle
+ * @pdata: private data of machine driver
+ * @card: sound card pointer reference
+ * @mbhc_cfg: MBHC config reference
+ *
+ * Returns 0 on success or ret on failure.
+ */
+int msm_ext_cdc_init(struct platform_device *pdev,
+ struct msm_asoc_mach_data *pdata,
+ struct snd_soc_card **card,
+ struct wcd_mbhc_config *wcd_mbhc_cfg_ptr1)
+{
+ int ret = 0;
+
+ wcd_mbhc_cfg_ptr = wcd_mbhc_cfg_ptr1;
+ pdev->id = 0;
+ wcd_mbhc_cfg_ptr->moisture_en = true;
+ wcd_mbhc_cfg_ptr->mbhc_micbias = MIC_BIAS_2;
+ wcd_mbhc_cfg_ptr->anc_micbias = MIC_BIAS_2;
+ wcd_mbhc_cfg_ptr->enable_anc_mic_detect = false;
+
+ *card = populate_snd_card_dailinks(&pdev->dev, pdata->snd_card_val);
+ if (!(*card)) {
+ dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__);
+ ret = -EPROBE_DEFER;
+ goto err;
+ }
+ spdev = pdev;
+ platform_set_drvdata(pdev, *card);
+ snd_soc_card_set_drvdata(*card, pdata);
+ is_initial_boot = true;
+ pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node,
+ "qcom,hph-en1-gpio", 0);
+ if (!gpio_is_valid(pdata->hph_en1_gpio))
+ pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node,
+ "qcom,hph-en1-gpio", 0);
+ if (!gpio_is_valid(pdata->hph_en1_gpio) && (!pdata->hph_en1_gpio_p)) {
+ dev_dbg(&pdev->dev, "property %s not detected in node %s",
+ "qcom,hph-en1-gpio", pdev->dev.of_node->full_name);
+ }
+
+ pdata->hph_en0_gpio = of_get_named_gpio(pdev->dev.of_node,
+ "qcom,hph-en0-gpio", 0);
+ if (!gpio_is_valid(pdata->hph_en0_gpio))
+ pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node,
+ "qcom,hph-en0-gpio", 0);
+ if (!gpio_is_valid(pdata->hph_en0_gpio) && (!pdata->hph_en0_gpio_p)) {
+ dev_dbg(&pdev->dev, "property %s not detected in node %s",
+ "qcom,hph-en0-gpio", pdev->dev.of_node->full_name);
+ }
+
+ ret = msm_ext_prepare_hifi(pdata);
+ if (ret) {
+ dev_dbg(&pdev->dev, "msm_ext_prepare_hifi failed (%d)\n",
+ ret);
+ ret = 0;
+ }
+err:
+ return ret;
+}
+EXPORT_SYMBOL(msm_ext_cdc_init);
diff --git a/sound/soc/msm/msmfalcon-external.h b/sound/soc/msm/msmfalcon-external.h
new file mode 100644
index 000000000000..654cb70b9c84
--- /dev/null
+++ b/sound/soc/msm/msmfalcon-external.h
@@ -0,0 +1,50 @@
+/* Copyright (c) 2015-2016, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSMFALCON_EXTERNAL
+#define __MSMFALCON_EXTERNAL
+
+int msm_snd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params);
+int msm_ext_slimbus_2_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params);
+int msm_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params);
+int msm_proxy_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params);
+int msm_proxy_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params);
+int msm_audrx_init(struct snd_soc_pcm_runtime *rtd);
+int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params);
+struct snd_soc_card *populate_snd_card_dailinks(struct device *dev,
+ int snd_card_val);
+int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params);
+#ifdef CONFIG_SND_SOC_EXT_CODEC
+int msm_ext_cdc_init(struct platform_device *, struct msm_asoc_mach_data *,
+ struct snd_soc_card **, struct wcd_mbhc_config *);
+void msm_ext_register_audio_notifier(void);
+#else
+inline int msm_ext_cdc_init(struct platform_device *pdev,
+ struct msm_asoc_mach_data *pdata,
+ struct snd_soc_card **card,
+ struct wcd_mbhc_config *wcd_mbhc_cfg_ptr1)
+{
+ return 0;
+}
+
+inline void msm_ext_register_audio_notifier(void)
+{
+}
+#endif
+#endif
diff --git a/sound/soc/msm/msmfalcon-internal.c b/sound/soc/msm/msmfalcon-internal.c
new file mode 100644
index 000000000000..180ff492e9e9
--- /dev/null
+++ b/sound/soc/msm/msmfalcon-internal.c
@@ -0,0 +1,2970 @@
+/* Copyright (c) 2015-2016, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <sound/pcm_params.h>
+#include "qdsp6v2/msm-pcm-routing-v2.h"
+#include "msm-audio-pinctrl.h"
+#include "msmfalcon-common.h"
+#include "../codecs/msm8x16/msm8x16-wcd.h"
+
+#define __CHIPSET__ "MSMFALCON "
+#define MSM_DAILINK_NAME(name) (__CHIPSET__#name)
+
+#define DEFAULT_MCLK_RATE 9600000
+#define NATIVE_MCLK_RATE 11289600
+
+#define WCD_MBHC_DEF_RLOADS 5
+
+#define WCN_CDC_SLIM_RX_CH_MAX 2
+#define WCN_CDC_SLIM_TX_CH_MAX 3
+
+enum {
+ INT0_MI2S = 0,
+ INT1_MI2S,
+ INT2_MI2S,
+ INT3_MI2S,
+ INT4_MI2S,
+ INT5_MI2S,
+ INT6_MI2S,
+ INT_MI2S_MAX,
+};
+
+enum {
+ BT_SLIM7,
+ FM_SLIM8,
+ SLIM_MAX,
+};
+
+/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */
+static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = {
+ {0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */
+ {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */
+ {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */
+ {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */
+ {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */
+ {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */
+ {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */
+ {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */
+};
+
+static struct afe_clk_set int_mi2s_clk[INT_MI2S_MAX] = {
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_INT0_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ },
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_INT1_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ },
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_INT2_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ },
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_INT3_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ },
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_INT4_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ },
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_INT5_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ },
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_INT6_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ },
+};
+
+struct dev_config {
+ u32 sample_rate;
+ u32 bit_format;
+ u32 channels;
+};
+
+/* Default configuration of MI2S channels */
+static struct dev_config int_mi2s_cfg[] = {
+ [INT0_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+ [INT1_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [INT2_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [INT3_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [INT4_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [INT5_MI2S] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+ [INT6_MI2S] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+};
+
+static struct dev_config bt_fm_cfg[] = {
+ [BT_SLIM7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [FM_SLIM8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+};
+
+static char const *int_mi2s_rate_text[] = {"KHZ_8", "KHZ_16",
+ "KHZ_32", "KHZ_44P1", "KHZ_48",
+ "KHZ_96", "KHZ_192"};
+static const char *const int_mi2s_ch_text[] = {"One", "Two"};
+static const char *const int_mi2s_tx_ch_text[] = {"One", "Two",
+ "Three", "Four"};
+static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"};
+static const char *const loopback_mclk_text[] = {"DISABLE", "ENABLE"};
+static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_48"};
+
+static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_sample_rate, int_mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_chs, int_mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(int2_mi2s_tx_sample_rate, int_mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(int2_mi2s_tx_chs, int_mi2s_tx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(int2_mi2s_tx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(int3_mi2s_tx_sample_rate, int_mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(int3_mi2s_tx_chs, int_mi2s_tx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(int3_mi2s_tx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_sample_rate, int_mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_chs, int_mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(int5_mi2s_tx_chs, int_mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(loopback_mclk_en, loopback_mclk_text);
+static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text);
+
+static int msm_dmic_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event);
+static int msm_int_enable_dig_cdc_clk(struct snd_soc_codec *codec, int enable,
+ bool dapm);
+static int msm_int_mclk0_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event);
+static int msm_int_mi2s_snd_startup(struct snd_pcm_substream *substream);
+static void msm_int_mi2s_snd_shutdown(struct snd_pcm_substream *substream);
+
+static struct wcd_mbhc_config *mbhc_cfg_ptr;
+
+static int int_mi2s_get_bit_format_val(int bit_format)
+{
+ int val = 0;
+
+ switch (bit_format) {
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ val = 2;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ val = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ val = 0;
+ break;
+ }
+ return val;
+}
+
+static int int_mi2s_get_bit_format(int val)
+{
+ int bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
+
+ switch (val) {
+ case 0:
+ bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ case 1:
+ bit_fmt = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 2:
+ bit_fmt = SNDRV_PCM_FORMAT_S24_3LE;
+ break;
+ default:
+ bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ return bit_fmt;
+}
+
+static int int_mi2s_get_port_idx(struct snd_kcontrol *kcontrol)
+{
+ int port_id = 0;
+
+ if (strnstr(kcontrol->id.name, "INT0_MI2S", sizeof("INT0_MI2S")))
+ port_id = INT0_MI2S;
+ else if (strnstr(kcontrol->id.name, "INT2_MI2S", sizeof("INT2_MI2S")))
+ port_id = INT2_MI2S;
+ else if (strnstr(kcontrol->id.name, "INT3_MI2S", sizeof("INT3_MI2S")))
+ port_id = INT3_MI2S;
+ else if (strnstr(kcontrol->id.name, "INT4_MI2S", sizeof("INT4_MI2S")))
+ port_id = INT4_MI2S;
+ else {
+ pr_err("%s: unsupported channel: %s",
+ __func__, kcontrol->id.name);
+ return -EINVAL;
+ }
+
+ return port_id;
+}
+
+static int int_mi2s_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = int_mi2s_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ ucontrol->value.enumerated.item[0] =
+ int_mi2s_get_bit_format_val(int_mi2s_cfg[ch_num].bit_format);
+
+ pr_debug("%s: int_mi2s[%d]_bit_format = %d, ucontrol value = %d\n",
+ __func__, ch_num, int_mi2s_cfg[ch_num].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int int_mi2s_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = int_mi2s_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ int_mi2s_cfg[ch_num].bit_format =
+ int_mi2s_get_bit_format(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: int_mi2s[%d]_rx_bit_format = %d, ucontrol value = %d\n",
+ __func__, ch_num, int_mi2s_cfg[ch_num].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static inline int param_is_mask(int p)
+{
+ return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
+ (p <= SNDRV_PCM_HW_PARAM_LAST_MASK);
+}
+
+static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p,
+ int n)
+{
+ return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
+}
+
+static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned bit)
+{
+ if (bit >= SNDRV_MASK_MAX)
+ return;
+ if (param_is_mask(n)) {
+ struct snd_mask *m = param_to_mask(p, n);
+
+ m->bits[0] = 0;
+ m->bits[1] = 0;
+ m->bits[bit >> 5] |= (1 << (bit & 31));
+ }
+}
+
+static int int_mi2s_get_sample_rate_val(int sample_rate)
+{
+ int sample_rate_val;
+
+ switch (sample_rate) {
+ case SAMPLING_RATE_8KHZ:
+ sample_rate_val = 0;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ sample_rate_val = 1;
+ break;
+ case SAMPLING_RATE_32KHZ:
+ sample_rate_val = 2;
+ break;
+ case SAMPLING_RATE_44P1KHZ:
+ sample_rate_val = 3;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ sample_rate_val = 4;
+ break;
+ case SAMPLING_RATE_96KHZ:
+ sample_rate_val = 5;
+ break;
+ case SAMPLING_RATE_192KHZ:
+ sample_rate_val = 6;
+ break;
+ default:
+ sample_rate_val = 4;
+ break;
+ }
+ return sample_rate_val;
+}
+
+static int int_mi2s_get_sample_rate(int value)
+{
+ int sample_rate;
+
+ switch (value) {
+ case 0:
+ sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ case 1:
+ sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 2:
+ sample_rate = SAMPLING_RATE_32KHZ;
+ break;
+ case 3:
+ sample_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 4:
+ sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 5:
+ sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 6:
+ sample_rate = SAMPLING_RATE_192KHZ;
+ break;
+ default:
+ sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+ return sample_rate;
+}
+
+static int int_mi2s_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = int_mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ int_mi2s_cfg[idx].sample_rate =
+ int_mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: idx[%d]_sample_rate = %d, item = %d\n", __func__,
+ idx, int_mi2s_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int int_mi2s_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = int_mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.enumerated.item[0] =
+ int_mi2s_get_sample_rate_val(int_mi2s_cfg[idx].sample_rate);
+
+ pr_debug("%s: idx[%d]_sample_rate = %d, item = %d\n", __func__,
+ idx, int_mi2s_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int int_mi2s_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = int_mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ pr_debug("%s: int_mi2s_[%d]_rx_ch = %d\n", __func__,
+ idx, int_mi2s_cfg[idx].channels);
+ ucontrol->value.enumerated.item[0] = int_mi2s_cfg[idx].channels - 1;
+
+ return 0;
+}
+
+static int int_mi2s_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = int_mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ int_mi2s_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1;
+ pr_debug("%s: int_mi2s_[%d]_ch = %d\n", __func__,
+ idx, int_mi2s_cfg[idx].channels);
+
+ return 1;
+}
+
+static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = {
+ SND_SOC_DAPM_SUPPLY_S("INT_MCLK0", -1, SND_SOC_NOPM, 0, 0,
+ msm_int_mclk0_event, SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIC("Handset Mic", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Secondary Mic", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic1", msm_dmic_event),
+ SND_SOC_DAPM_MIC("Digital Mic2", msm_dmic_event),
+ SND_SOC_DAPM_MIC("Digital Mic3", msm_dmic_event),
+ SND_SOC_DAPM_MIC("Digital Mic4", msm_dmic_event),
+};
+
+static int msm_config_hph_compander_gpio(bool enable)
+{
+ int ret = 0;
+
+ pr_debug("%s: %s HPH Compander\n", __func__,
+ enable ? "Enable" : "Disable");
+
+ if (enable) {
+ ret = msm_gpioset_activate(CLIENT_WCD, "comp_gpio");
+ if (ret) {
+ pr_err("%s: gpio set cannot be activated %s\n",
+ __func__, "comp_gpio");
+ goto done;
+ }
+ } else {
+ ret = msm_gpioset_suspend(CLIENT_WCD, "comp_gpio");
+ if (ret) {
+ pr_err("%s: gpio set cannot be de-activated %s\n",
+ __func__, "comp_gpio");
+ goto done;
+ }
+ }
+
+done:
+ return ret;
+}
+
+static int is_ext_spk_gpio_support(struct platform_device *pdev,
+ struct msm_asoc_mach_data *pdata)
+{
+ const char *spk_ext_pa = "qcom,msm-spk-ext-pa";
+
+ pr_debug("%s:Enter\n", __func__);
+
+ pdata->spk_ext_pa_gpio = of_get_named_gpio(pdev->dev.of_node,
+ spk_ext_pa, 0);
+
+ if (pdata->spk_ext_pa_gpio < 0) {
+ dev_dbg(&pdev->dev,
+ "%s: missing %s in dt node\n", __func__, spk_ext_pa);
+ } else {
+ if (!gpio_is_valid(pdata->spk_ext_pa_gpio)) {
+ pr_err("%s: Invalid external speaker gpio: %d",
+ __func__, pdata->spk_ext_pa_gpio);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static int enable_spk_ext_pa(struct snd_soc_codec *codec, int enable)
+{
+ struct snd_soc_card *card = codec->component.card;
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ int ret;
+
+ if (!gpio_is_valid(pdata->spk_ext_pa_gpio)) {
+ pr_err("%s: Invalid gpio: %d\n", __func__,
+ pdata->spk_ext_pa_gpio);
+ return false;
+ }
+
+ pr_debug("%s: %s external speaker PA\n", __func__,
+ enable ? "Enable" : "Disable");
+
+ if (enable) {
+ ret = msm_gpioset_activate(CLIENT_WCD, "ext_spk_gpio");
+ if (ret) {
+ pr_err("%s: gpio set cannot be de-activated %s\n",
+ __func__, "ext_spk_gpio");
+ return ret;
+ }
+ gpio_set_value_cansleep(pdata->spk_ext_pa_gpio, enable);
+ } else {
+ gpio_set_value_cansleep(pdata->spk_ext_pa_gpio, enable);
+ ret = msm_gpioset_suspend(CLIENT_WCD, "ext_spk_gpio");
+ if (ret) {
+ pr_err("%s: gpio set cannot be de-activated %s\n",
+ __func__, "ext_spk_gpio");
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static int int_mi2s_get_idx_from_beid(int32_t be_id)
+{
+ int idx = 0;
+
+ switch (be_id) {
+ case MSM_BACKEND_DAI_INT0_MI2S_RX:
+ idx = INT0_MI2S;
+ break;
+ case MSM_BACKEND_DAI_INT2_MI2S_TX:
+ idx = INT2_MI2S;
+ break;
+ case MSM_BACKEND_DAI_INT3_MI2S_TX:
+ idx = INT3_MI2S;
+ break;
+ case MSM_BACKEND_DAI_INT4_MI2S_RX:
+ idx = INT4_MI2S;
+ break;
+ case MSM_BACKEND_DAI_INT5_MI2S_TX:
+ idx = INT5_MI2S;
+ break;
+ default:
+ idx = INT0_MI2S;
+ break;
+ }
+
+ return idx;
+}
+
+static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ pr_debug("%s()\n", __func__);
+ rate->min = rate->max = 48000;
+ channels->min = channels->max = 2;
+
+ return 0;
+}
+
+static int int_mi2s_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+ int idx;
+
+ pr_debug("%s: format = %d, rate = %d\n",
+ __func__, params_format(params), params_rate(params));
+
+ switch (dai_link->be_id) {
+ case MSM_BACKEND_DAI_INT0_MI2S_RX:
+ case MSM_BACKEND_DAI_INT2_MI2S_TX:
+ case MSM_BACKEND_DAI_INT3_MI2S_TX:
+ case MSM_BACKEND_DAI_INT4_MI2S_RX:
+ case MSM_BACKEND_DAI_INT5_MI2S_TX:
+ idx = int_mi2s_get_idx_from_beid(dai_link->be_id);
+ rate->min = rate->max = int_mi2s_cfg[idx].sample_rate;
+ channels->min = channels->max =
+ int_mi2s_cfg[idx].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ int_mi2s_cfg[idx].bit_format);
+ break;
+ default:
+ rate->min = rate->max = SAMPLING_RATE_48KHZ;
+ break;
+ }
+ return 0;
+}
+
+static int msm_btfm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ switch (dai_link->be_id) {
+ case MSM_BACKEND_DAI_SLIMBUS_7_RX:
+ case MSM_BACKEND_DAI_SLIMBUS_7_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ bt_fm_cfg[BT_SLIM7].bit_format);
+ rate->min = rate->max = bt_fm_cfg[BT_SLIM7].sample_rate;
+ channels->min = channels->max =
+ bt_fm_cfg[BT_SLIM7].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_8_TX:
+ rate->min = rate->max = bt_fm_cfg[FM_SLIM8].sample_rate;
+ channels->min = channels->max =
+ bt_fm_cfg[FM_SLIM8].channels;
+ break;
+
+ default:
+ rate->min = rate->max = SAMPLING_RATE_48KHZ;
+ break;
+ }
+ return 0;
+}
+
+static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] =
+ (int_mi2s_cfg[INT5_MI2S].channels/2 - 1);
+ pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__,
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int_mi2s_cfg[INT5_MI2S].channels =
+ roundup_pow_of_two(ucontrol->value.integer.value[0] + 2);
+
+ pr_debug("%s: msm_vi_feed_tx_ch = %d\n",
+ __func__, int_mi2s_cfg[INT5_MI2S].channels);
+ return 1;
+}
+
+static int msm_int_enable_dig_cdc_clk(struct snd_soc_codec *codec,
+ int enable, bool dapm)
+{
+ int ret = 0;
+ struct msm_asoc_mach_data *pdata = NULL;
+ int clk_freq_in_hz;
+ bool int_mclk0_freq_chg = false;
+
+ pdata = snd_soc_card_get_drvdata(codec->component.card);
+ pr_debug("%s: enable %d mclk ref counter %d\n",
+ __func__, enable,
+ atomic_read(&pdata->int_mclk0_rsc_ref));
+ if (enable) {
+ if (int_mi2s_cfg[INT0_MI2S].sample_rate ==
+ SAMPLING_RATE_44P1KHZ)
+ clk_freq_in_hz = NATIVE_MCLK_RATE;
+ else
+ clk_freq_in_hz = pdata->mclk_freq;
+
+ if (pdata->digital_cdc_core_clk.clk_freq_in_hz
+ != clk_freq_in_hz)
+ int_mclk0_freq_chg = true;
+ if (!atomic_read(&pdata->int_mclk0_rsc_ref) ||
+ int_mclk0_freq_chg) {
+ cancel_delayed_work_sync(
+ &pdata->disable_int_mclk0_work);
+ mutex_lock(&pdata->cdc_int_mclk0_mutex);
+ if (atomic_read(&pdata->int_mclk0_enabled) == false ||
+ int_mclk0_freq_chg) {
+ pdata->digital_cdc_core_clk.clk_freq_in_hz =
+ clk_freq_in_hz;
+ pdata->digital_cdc_core_clk.enable = 1;
+ ret = afe_set_lpass_clock_v2(
+ AFE_PORT_ID_INT0_MI2S_RX,
+ &pdata->digital_cdc_core_clk);
+ if (ret < 0) {
+ pr_err("%s: failed to enable CCLK\n",
+ __func__);
+ mutex_unlock(
+ &pdata->cdc_int_mclk0_mutex);
+ return ret;
+ }
+ pr_debug("enabled digital codec core clk\n");
+ atomic_set(&pdata->int_mclk0_enabled, true);
+ }
+ mutex_unlock(&pdata->cdc_int_mclk0_mutex);
+ }
+ atomic_inc(&pdata->int_mclk0_rsc_ref);
+ } else {
+ cancel_delayed_work_sync(&pdata->disable_int_mclk0_work);
+ mutex_lock(&pdata->cdc_int_mclk0_mutex);
+ if (atomic_read(&pdata->int_mclk0_enabled) == true) {
+ pdata->digital_cdc_core_clk.enable = 0;
+ ret = afe_set_lpass_clock_v2(
+ AFE_PORT_ID_INT0_MI2S_RX,
+ &pdata->digital_cdc_core_clk);
+ if (ret < 0)
+ pr_err("%s: failed to disable CCLK\n",
+ __func__);
+ atomic_set(&pdata->int_mclk0_enabled, false);
+ }
+ mutex_unlock(&pdata->cdc_int_mclk0_mutex);
+ }
+ return ret;
+}
+
+static int loopback_mclk_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s\n", __func__);
+ return 0;
+}
+
+static int loopback_mclk_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret = -EINVAL;
+ struct msm_asoc_mach_data *pdata = NULL;
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+
+ pdata = snd_soc_card_get_drvdata(codec->component.card);
+ pr_debug("%s: mclk_rsc_ref %d enable %ld\n",
+ __func__, atomic_read(&pdata->int_mclk0_rsc_ref),
+ ucontrol->value.integer.value[0]);
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ ret = msm_gpioset_activate(CLIENT_WCD, "int_pdm");
+ if (ret) {
+ pr_err("%s: failed to enable the pri gpios: %d\n",
+ __func__, ret);
+ break;
+ }
+ mutex_lock(&pdata->cdc_int_mclk0_mutex);
+ if ((!atomic_read(&pdata->int_mclk0_rsc_ref)) &&
+ (!atomic_read(&pdata->int_mclk0_enabled))) {
+ pdata->digital_cdc_core_clk.enable = 1;
+ ret = afe_set_lpass_clock_v2(
+ AFE_PORT_ID_INT0_MI2S_RX,
+ &pdata->digital_cdc_core_clk);
+ if (ret < 0) {
+ pr_err("%s: failed to enable the MCLK: %d\n",
+ __func__, ret);
+ mutex_unlock(&pdata->cdc_int_mclk0_mutex);
+ ret = msm_gpioset_suspend(CLIENT_WCD,
+ "int_pdm");
+ if (ret)
+ pr_err("%s: failed to disable the pri gpios: %d\n",
+ __func__, ret);
+ break;
+ }
+ atomic_set(&pdata->int_mclk0_enabled, true);
+ }
+ mutex_unlock(&pdata->cdc_int_mclk0_mutex);
+ atomic_inc(&pdata->int_mclk0_rsc_ref);
+ msm8x16_wcd_mclk_enable(codec, 1, true);
+ break;
+ case 0:
+ if (atomic_read(&pdata->int_mclk0_rsc_ref) <= 0)
+ break;
+ msm8x16_wcd_mclk_enable(codec, 0, true);
+ mutex_lock(&pdata->cdc_int_mclk0_mutex);
+ if ((!atomic_dec_return(&pdata->int_mclk0_rsc_ref)) &&
+ (atomic_read(&pdata->int_mclk0_enabled))) {
+ pdata->digital_cdc_core_clk.enable = 0;
+ ret = afe_set_lpass_clock_v2(
+ AFE_PORT_ID_INT0_MI2S_RX,
+ &pdata->digital_cdc_core_clk);
+ if (ret < 0) {
+ pr_err("%s: failed to disable the CCLK: %d\n",
+ __func__, ret);
+ mutex_unlock(&pdata->cdc_int_mclk0_mutex);
+ break;
+ }
+ atomic_set(&pdata->int_mclk0_enabled, false);
+ }
+ mutex_unlock(&pdata->cdc_int_mclk0_mutex);
+ ret = msm_gpioset_suspend(CLIENT_WCD, "int_pdm");
+ if (ret)
+ pr_err("%s: failed to disable the pri gpios: %d\n",
+ __func__, ret);
+ break;
+ default:
+ pr_err("%s: Unexpected input value\n", __func__);
+ break;
+ }
+ return ret;
+}
+
+static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ /*
+ * Slimbus_7_Rx/Tx sample rate values should always be in sync (same)
+ * when used for BT_SCO use case. Return either Rx or Tx sample rate
+ * value.
+ */
+ switch (bt_fm_cfg[BT_SLIM7].sample_rate) {
+ case SAMPLING_RATE_48KHZ:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SAMPLING_RATE_8KHZ:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: sample rate = %d", __func__,
+ bt_fm_cfg[BT_SLIM7].sample_rate);
+
+ return 0;
+}
+
+static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 2:
+ bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 0:
+ default:
+ bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ }
+ pr_debug("%s: sample rates: slim7_rx = %d, value = %d\n",
+ __func__,
+ bt_fm_cfg[BT_SLIM7].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new msm_snd_controls[] = {
+ SOC_ENUM_EXT("INT0_MI2S_RX Format", int0_mi2s_rx_format,
+ int_mi2s_bit_format_get, int_mi2s_bit_format_put),
+ SOC_ENUM_EXT("INT2_MI2S_TX Format", int2_mi2s_tx_format,
+ int_mi2s_bit_format_get, int_mi2s_bit_format_put),
+ SOC_ENUM_EXT("INT3_MI2S_TX Format", int3_mi2s_tx_format,
+ int_mi2s_bit_format_get, int_mi2s_bit_format_put),
+ SOC_ENUM_EXT("INT0_MI2S_RX SampleRate", int0_mi2s_rx_sample_rate,
+ int_mi2s_sample_rate_get,
+ int_mi2s_sample_rate_put),
+ SOC_ENUM_EXT("INT2_MI2S_TX SampleRate", int2_mi2s_tx_sample_rate,
+ int_mi2s_sample_rate_get,
+ int_mi2s_sample_rate_put),
+ SOC_ENUM_EXT("INT3_MI2S_TX SampleRate", int3_mi2s_tx_sample_rate,
+ int_mi2s_sample_rate_get,
+ int_mi2s_sample_rate_put),
+ SOC_ENUM_EXT("INT0_MI2S_RX SampleRate", int0_mi2s_rx_sample_rate,
+ int_mi2s_sample_rate_get,
+ int_mi2s_sample_rate_put),
+ SOC_ENUM_EXT("INT2_MI2S_TX SampleRate", int2_mi2s_tx_sample_rate,
+ int_mi2s_sample_rate_get,
+ int_mi2s_sample_rate_put),
+ SOC_ENUM_EXT("INT3_MI2S_TX SampleRate", int3_mi2s_tx_sample_rate,
+ int_mi2s_sample_rate_get,
+ int_mi2s_sample_rate_put),
+ SOC_ENUM_EXT("INT0_MI2S_RX Channels", int0_mi2s_rx_chs,
+ int_mi2s_ch_get, int_mi2s_ch_put),
+ SOC_ENUM_EXT("INT2_MI2S_TX Channels", int2_mi2s_tx_chs,
+ int_mi2s_ch_get, int_mi2s_ch_put),
+ SOC_ENUM_EXT("INT3_MI2S_TX Channels", int3_mi2s_tx_chs,
+ int_mi2s_ch_get, int_mi2s_ch_put),
+ SOC_ENUM_EXT("Loopback MCLK", loopback_mclk_en,
+ loopback_mclk_get, loopback_mclk_put),
+ SOC_ENUM_EXT("BT SampleRate", bt_sample_rate,
+ msm_bt_sample_rate_get,
+ msm_bt_sample_rate_put),
+};
+
+static const struct snd_kcontrol_new msm_swr_controls[] = {
+ SOC_ENUM_EXT("INT4_MI2S_RX Format", int4_mi2s_rx_format,
+ int_mi2s_bit_format_get, int_mi2s_bit_format_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 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,
+ msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put),
+};
+
+static int msm_dmic_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct msm_asoc_mach_data *pdata = NULL;
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ int ret = 0;
+
+ pdata = snd_soc_card_get_drvdata(codec->component.card);
+ pr_debug("%s: event = %d\n", __func__, event);
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ ret = msm_gpioset_activate(CLIENT_WCD, "dmic_gpio");
+ if (ret < 0) {
+ pr_err("%s: gpio set cannot be activated %sd",
+ __func__, "dmic_gpio");
+ return ret;
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ret = msm_gpioset_suspend(CLIENT_WCD, "dmic_gpio");
+ if (ret < 0) {
+ pr_err("%s: gpio set cannot be de-activated %sd",
+ __func__, "dmic_gpio");
+ return ret;
+ }
+ break;
+ default:
+ pr_err("%s: invalid DAPM event %d\n", __func__, event);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int msm_int_mclk0_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct msm_asoc_mach_data *pdata = NULL;
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ int ret = 0;
+
+ pdata = snd_soc_card_get_drvdata(codec->component.card);
+ pr_debug("%s: event = %d\n", __func__, event);
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMD:
+ pr_debug("%s: mclk_res_ref = %d\n",
+ __func__, atomic_read(&pdata->int_mclk0_rsc_ref));
+ ret = msm_gpioset_suspend(CLIENT_WCD, "int_pdm");
+ if (ret < 0) {
+ pr_err("%s: gpio set cannot be de-activated %sd",
+ __func__, "int_pdm");
+ return ret;
+ }
+ if (atomic_read(&pdata->int_mclk0_rsc_ref) == 0) {
+ pr_debug("%s: disabling MCLK\n", __func__);
+ /* disable the codec mclk config*/
+ msm8x16_wcd_mclk_enable(codec, 0, true);
+ msm_int_enable_dig_cdc_clk(codec, 0, true);
+ }
+ break;
+ default:
+ pr_err("%s: invalid DAPM event %d\n", __func__, event);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int int_mi2s_get_port_id(int be_id)
+{
+ int afe_port_id;
+
+ switch (be_id) {
+ case MSM_BACKEND_DAI_INT0_MI2S_RX:
+ afe_port_id = AFE_PORT_ID_INT0_MI2S_RX;
+ break;
+ case MSM_BACKEND_DAI_INT2_MI2S_TX:
+ afe_port_id = AFE_PORT_ID_INT2_MI2S_TX;
+ break;
+ case MSM_BACKEND_DAI_INT3_MI2S_TX:
+ afe_port_id = AFE_PORT_ID_INT3_MI2S_TX;
+ break;
+ case MSM_BACKEND_DAI_INT4_MI2S_RX:
+ afe_port_id = AFE_PORT_ID_INT4_MI2S_RX;
+ break;
+ case MSM_BACKEND_DAI_INT5_MI2S_TX:
+ afe_port_id = AFE_PORT_ID_INT5_MI2S_TX;
+ break;
+ default:
+ pr_err("%s: Invalid be_id: %d\n", __func__, be_id);
+ afe_port_id = -EINVAL;
+ }
+
+ return afe_port_id;
+}
+
+static int int_mi2s_get_index(int port_id)
+{
+ int index;
+
+ switch (port_id) {
+ case AFE_PORT_ID_INT0_MI2S_RX:
+ index = INT0_MI2S;
+ break;
+ case AFE_PORT_ID_INT2_MI2S_TX:
+ index = INT2_MI2S;
+ break;
+ case AFE_PORT_ID_INT3_MI2S_TX:
+ index = INT3_MI2S;
+ break;
+ case AFE_PORT_ID_INT4_MI2S_RX:
+ index = INT4_MI2S;
+ break;
+ case AFE_PORT_ID_INT5_MI2S_TX:
+ index = INT5_MI2S;
+ break;
+ default:
+ pr_err("%s: Invalid port_id: %d\n", __func__, port_id);
+ index = -EINVAL;
+ }
+
+ return index;
+}
+
+static u32 get_int_mi2s_bits_per_sample(u32 bit_format)
+{
+ u32 bit_per_sample;
+
+ switch (bit_format) {
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ case SNDRV_PCM_FORMAT_S24_LE:
+ bit_per_sample = 32;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ bit_per_sample = 16;
+ break;
+ }
+
+ return bit_per_sample;
+}
+
+static void update_int_mi2s_clk_val(int idx, int stream)
+{
+ u32 bit_per_sample;
+
+ bit_per_sample =
+ get_int_mi2s_bits_per_sample(int_mi2s_cfg[idx].bit_format);
+ int_mi2s_clk[idx].clk_freq_in_hz =
+ (int_mi2s_cfg[idx].sample_rate * int_mi2s_cfg[idx].channels
+ * bit_per_sample);
+}
+
+static int int_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ int port_id = 0;
+ int index;
+
+ port_id = int_mi2s_get_port_id(rtd->dai_link->be_id);
+ if (IS_ERR_VALUE(port_id)) {
+ dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__);
+ ret = port_id;
+ goto done;
+ }
+ index = int_mi2s_get_index(port_id);
+ if (index < 0) {
+ dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__);
+ ret = port_id;
+ goto done;
+ }
+ if (enable) {
+ update_int_mi2s_clk_val(index, substream->stream);
+ dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__,
+ int_mi2s_clk[index].clk_freq_in_hz);
+ }
+
+ int_mi2s_clk[index].enable = enable;
+ ret = afe_set_lpass_clock_v2(port_id,
+ &int_mi2s_clk[index]);
+ if (ret < 0) {
+ dev_err(rtd->card->dev,
+ "%s: afe lpass clock failed for port 0x%x , err:%d\n",
+ __func__, port_id, ret);
+ goto done;
+ }
+
+done:
+ return ret;
+}
+
+static int msm_swr_mi2s_snd_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+
+ ret = int_mi2s_set_sclk(substream, true);
+ if (ret < 0) {
+ pr_err("%s: failed to enable sclk %d\n",
+ __func__, ret);
+ return ret;
+ }
+ /* Enable the codec mclk config */
+ ret = msm_gpioset_activate(CLIENT_WCD, "swr_pin");
+ if (ret < 0) {
+ pr_err("%s: gpio set cannot be activated %sd",
+ __func__, "swr_pin");
+ return ret;
+ }
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ pr_err("%s: set fmt cpu dai failed; ret=%d\n", __func__, ret);
+
+ return ret;
+}
+
+static void msm_swr_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
+{
+ int ret;
+
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+
+ ret = int_mi2s_set_sclk(substream, false);
+ if (ret < 0)
+ pr_err("%s:clock disable failed; ret=%d\n", __func__,
+ ret);
+}
+
+static int msm_int_mi2s_snd_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_codec *codec = rtd->codec;
+ int ret = 0;
+
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+
+ ret = int_mi2s_set_sclk(substream, true);
+ if (ret < 0) {
+ pr_err("%s: failed to enable sclk %d\n",
+ __func__, ret);
+ return ret;
+ }
+ ret = msm_int_enable_dig_cdc_clk(codec, 1, true);
+ if (ret < 0) {
+ pr_err("failed to enable mclk\n");
+ return ret;
+ }
+ /* Enable the codec mclk config */
+ ret = msm_gpioset_activate(CLIENT_WCD, "int_pdm");
+ if (ret < 0) {
+ pr_err("%s: gpio set cannot be activated %s\n",
+ __func__, "int_pdm");
+ return ret;
+ }
+ msm8x16_wcd_mclk_enable(codec, 1, true);
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ pr_err("%s: set fmt cpu dai failed; ret=%d\n", __func__, ret);
+
+ return ret;
+}
+
+static void msm_int_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
+{
+ int ret;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+
+ ret = int_mi2s_set_sclk(substream, false);
+ if (ret < 0)
+ pr_err("%s:clock disable failed; ret=%d\n", __func__,
+ ret);
+ if (atomic_read(&pdata->int_mclk0_rsc_ref) > 0) {
+ atomic_dec(&pdata->int_mclk0_rsc_ref);
+ pr_debug("%s: decrementing mclk_res_ref %d\n",
+ __func__,
+ atomic_read(&pdata->int_mclk0_rsc_ref));
+ }
+}
+
+static void *def_msm_int_wcd_mbhc_cal(void)
+{
+ void *msm_int_wcd_cal;
+ struct wcd_mbhc_btn_detect_cfg *btn_cfg;
+ u16 *btn_low, *btn_high;
+
+ msm_int_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS,
+ WCD_MBHC_DEF_RLOADS), GFP_KERNEL);
+ if (!msm_int_wcd_cal)
+ return NULL;
+
+#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(msm_int_wcd_cal)->X) = (Y))
+ S(v_hs_max, 1500);
+#undef S
+#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(msm_int_wcd_cal)->X) = (Y))
+ S(num_btn, WCD_MBHC_DEF_BUTTONS);
+#undef S
+
+
+ btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(msm_int_wcd_cal);
+ btn_low = btn_cfg->_v_btn_low;
+ btn_high = ((void *)&btn_cfg->_v_btn_low) +
+ (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn);
+
+ /*
+ * In SW we are maintaining two sets of threshold register
+ * one for current source and another for Micbias.
+ * all btn_low corresponds to threshold for current source
+ * all bt_high corresponds to threshold for Micbias
+ * Below thresholds are based on following resistances
+ * 0-70 == Button 0
+ * 110-180 == Button 1
+ * 210-290 == Button 2
+ * 360-680 == Button 3
+ */
+ btn_low[0] = 75;
+ btn_high[0] = 75;
+ btn_low[1] = 150;
+ btn_high[1] = 150;
+ btn_low[2] = 225;
+ btn_high[2] = 225;
+ btn_low[3] = 450;
+ btn_high[3] = 450;
+ btn_low[4] = 500;
+ btn_high[4] = 500;
+
+ return msm_int_wcd_cal;
+}
+
+static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm =
+ snd_soc_codec_get_dapm(codec);
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = -ENOMEM;
+
+ pr_debug("%s(),dev_name%s\n", __func__, dev_name(cpu_dai->dev));
+
+ snd_soc_add_codec_controls(codec, msm_snd_controls,
+ ARRAY_SIZE(msm_snd_controls));
+
+ snd_soc_add_codec_controls(codec, msm_common_snd_controls,
+ ARRAY_SIZE(msm_snd_controls));
+
+ snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets,
+ ARRAY_SIZE(msm_int_dapm_widgets));
+
+ snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Secondary Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2");
+
+ snd_soc_dapm_ignore_suspend(dapm, "EAR");
+ snd_soc_dapm_ignore_suspend(dapm, "HEADPHONE");
+ snd_soc_dapm_ignore_suspend(dapm, "SPK_OUT");
+ snd_soc_dapm_ignore_suspend(dapm, "AMIC1");
+ snd_soc_dapm_ignore_suspend(dapm, "AMIC2");
+ snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC1");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC2");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC3");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC4");
+
+ snd_soc_dapm_sync(dapm);
+
+ msm8x16_wcd_spk_ext_pa_cb(enable_spk_ext_pa, codec);
+ msm8x16_wcd_hph_comp_cb(msm_config_hph_compander_gpio, codec);
+
+ mbhc_cfg_ptr->calibration = def_msm_int_wcd_mbhc_cal();
+ if (mbhc_cfg_ptr->calibration) {
+ ret = msm8x16_wcd_hs_detect(codec, mbhc_cfg_ptr);
+ if (ret) {
+ pr_err("%s: msm8x16_wcd_hs_detect failed\n", __func__);
+ kfree(mbhc_cfg_ptr->calibration);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static int msm_swr_audrx_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm =
+ snd_soc_codec_get_dapm(codec);
+
+ snd_soc_add_codec_controls(codec, msm_swr_controls,
+ ARRAY_SIZE(msm_swr_controls));
+
+ snd_soc_dapm_ignore_suspend(dapm, "AIF1_SWR Playback");
+ snd_soc_dapm_ignore_suspend(dapm, "VIfeed_SWR");
+ snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT");
+ snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT");
+ snd_soc_dapm_ignore_suspend(dapm, "AIF1_SWR VI");
+ snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_SWR");
+
+ snd_soc_dapm_sync(dapm);
+
+ return 0;
+}
+
+static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd)
+{
+ unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158};
+ unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161};
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+
+ return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
+ tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
+}
+
+static int msm_wcn_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+ u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX];
+ u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
+ int ret;
+
+ dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__,
+ codec_dai->name, codec_dai->id);
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
+ if (ret) {
+ dev_err(rtd->dev,
+ "%s: failed to get BTFM codec chan map\n, err:%d\n",
+ __func__, ret);
+ goto exit;
+ }
+
+ dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) be_id %d\n",
+ __func__, tx_ch_cnt, dai_link->be_id);
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch);
+ if (ret)
+ dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n",
+ __func__, ret);
+
+exit:
+ return ret;
+}
+
+static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width,
+ int slots)
+{
+ unsigned int slot_mask = 0;
+ int i, j;
+ unsigned int *slot_offset;
+
+ for (i = TDM_0; i < TDM_PORT_MAX; i++) {
+ slot_offset = tdm_slot_offset[i];
+
+ for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) {
+ if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID)
+ slot_mask |=
+ (1 << ((slot_offset[j] * 8) / slot_width));
+ else
+ break;
+ }
+ }
+
+ return slot_mask;
+}
+
+static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+ int channels, slot_width, slots;
+ unsigned int slot_mask;
+ unsigned int *slot_offset;
+ int offset_channels = 0;
+ int i;
+
+ pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
+
+ channels = params_channels(params);
+ switch (channels) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ case SNDRV_PCM_FORMAT_S24_LE:
+ case SNDRV_PCM_FORMAT_S16_LE:
+ /*
+ * up to 8 channels HW config should
+ * use 32 bit slot width for max support of
+ * stream bit width. (slot_width > bit_width)
+ */
+ slot_width = 32;
+ break;
+ default:
+ pr_err("%s: invalid param format 0x%x\n",
+ __func__, params_format(params));
+ return -EINVAL;
+ }
+ slots = 8;
+ slot_mask = tdm_param_set_slot_mask(cpu_dai->id,
+ slot_width,
+ slots);
+ if (!slot_mask) {
+ pr_err("%s: invalid slot_mask 0x%x\n",
+ __func__, slot_mask);
+ return -EINVAL;
+ }
+ break;
+ default:
+ pr_err("%s: invalid param channels %d\n",
+ __func__, channels);
+ return -EINVAL;
+ }
+ /* currently only supporting TDM_RX_0 and TDM_TX_0 */
+ switch (cpu_dai->id) {
+ case AFE_PORT_ID_PRIMARY_TDM_RX:
+ case AFE_PORT_ID_SECONDARY_TDM_RX:
+ case AFE_PORT_ID_TERTIARY_TDM_RX:
+ case AFE_PORT_ID_QUATERNARY_TDM_RX:
+ case AFE_PORT_ID_PRIMARY_TDM_TX:
+ case AFE_PORT_ID_SECONDARY_TDM_TX:
+ case AFE_PORT_ID_TERTIARY_TDM_TX:
+ case AFE_PORT_ID_QUATERNARY_TDM_TX:
+ slot_offset = tdm_slot_offset[TDM_0];
+ break;
+ default:
+ pr_err("%s: dai id 0x%x not supported\n",
+ __func__, cpu_dai->id);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) {
+ if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID)
+ offset_channels++;
+ else
+ break;
+ }
+
+ if (offset_channels == 0) {
+ pr_err("%s: slot offset not supported, offset_channels %d\n",
+ __func__, offset_channels);
+ return -EINVAL;
+ }
+
+ if (channels > offset_channels) {
+ pr_err("%s: channels %d exceed offset_channels %d\n",
+ __func__, channels, offset_channels);
+ return -EINVAL;
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
+ slots, slot_width);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm slot, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
+ channels, slot_offset);
+ if (ret < 0) {
+ pr_err("%s: failed to set channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ } else {
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0,
+ slots, slot_width);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm slot, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai, channels,
+ slot_offset, 0, NULL);
+ if (ret < 0) {
+ pr_err("%s: failed to set channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ }
+end:
+ return ret;
+}
+
+static struct snd_soc_ops msm_tdm_be_ops = {
+ .hw_params = msm_tdm_snd_hw_params
+};
+
+static struct snd_soc_ops msm_wcn_ops = {
+ .hw_params = msm_wcn_hw_params,
+};
+
+static struct snd_soc_ops msm_mi2s_be_ops = {
+ .startup = msm_mi2s_snd_startup,
+ .shutdown = msm_mi2s_snd_shutdown,
+};
+
+static struct snd_soc_ops msm_aux_pcm_be_ops = {
+ .startup = msm_aux_pcm_snd_startup,
+ .shutdown = msm_aux_pcm_snd_shutdown,
+};
+
+static struct snd_soc_ops msm_int_mi2s_be_ops = {
+ .startup = msm_int_mi2s_snd_startup,
+ .shutdown = msm_int_mi2s_snd_shutdown,
+};
+
+static struct snd_soc_ops msm_swr_mi2s_be_ops = {
+ .startup = msm_swr_mi2s_snd_startup,
+ .shutdown = msm_swr_mi2s_snd_shutdown,
+};
+
+/* Digital audio interface glue - connects codec <---> CPU */
+static struct snd_soc_dai_link msm_int_dai[] = {
+ /* FrontEnd DAI Links */
+ {/* hw:x,0 */
+ .name = MSM_DAILINK_NAME(Media1),
+ .stream_name = "MultiMedia1",
+ .cpu_dai_name = "MultiMedia1",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA1
+ },
+ {/* hw:x,1 */
+ .name = MSM_DAILINK_NAME(Media2),
+ .stream_name = "MultiMedia2",
+ .cpu_dai_name = "MultiMedia2",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA2,
+ },
+ {/* hw:x,2 */
+ .name = "VoiceMMode1",
+ .stream_name = "VoiceMMode1",
+ .cpu_dai_name = "VoiceMMode1",
+ .platform_name = "msm-pcm-voice",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_VOICEMMODE1,
+ },
+ {/* hw:x,3 */
+ .name = "MSM VoIP",
+ .stream_name = "VoIP",
+ .cpu_dai_name = "VoIP",
+ .platform_name = "msm-voip-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_VOIP,
+ },
+ {/* hw:x,4 */
+ .name = MSM_DAILINK_NAME(ULL),
+ .stream_name = "ULL",
+ .cpu_dai_name = "MultiMedia3",
+ .platform_name = "msm-pcm-dsp.2",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA3,
+ },
+ /* Hostless PCM purpose */
+ {/* hw:x,5 */
+ .name = "INT4 MI2S_RX Hostless",
+ .stream_name = "INT4 MI2S_RX Hostless",
+ .cpu_dai_name = "INT4_MI2S_RX_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dailink has playback support */
+ .ignore_pmdown_time = 1,
+ /* This dainlink has MI2S support */
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,6 */
+ .name = "MSM AFE-PCM RX",
+ .stream_name = "AFE-PROXY RX",
+ .cpu_dai_name = "msm-dai-q6-dev.241",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .platform_name = "msm-pcm-afe",
+ .ignore_suspend = 1,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ },
+ {/* hw:x,7 */
+ .name = "MSM AFE-PCM TX",
+ .stream_name = "AFE-PROXY TX",
+ .cpu_dai_name = "msm-dai-q6-dev.240",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .platform_name = "msm-pcm-afe",
+ .ignore_suspend = 1,
+ },
+ {/* hw:x,8 */
+ .name = MSM_DAILINK_NAME(Compress1),
+ .stream_name = "Compress1",
+ .cpu_dai_name = "MultiMedia4",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA4,
+ },
+ {/* hw:x,9*/
+ .name = "AUXPCM Hostless",
+ .stream_name = "AUXPCM Hostless",
+ .cpu_dai_name = "AUXPCM_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,10 */
+ .name = "SLIMBUS_1 Hostless",
+ .stream_name = "SLIMBUS_1 Hostless",
+ .cpu_dai_name = "SLIMBUS1_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1, /* dai link has playback support */
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,11 */
+ .name = "SLIMBUS_3 Hostless",
+ .stream_name = "SLIMBUS_3 Hostless",
+ .cpu_dai_name = "SLIMBUS3_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1, /* dai link has playback support */
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,12 */
+ .name = "SLIMBUS_4 Hostless",
+ .stream_name = "SLIMBUS_4 Hostless",
+ .cpu_dai_name = "SLIMBUS4_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1, /* dai link has playback support */
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,13 */
+ .name = MSM_DAILINK_NAME(LowLatency),
+ .stream_name = "MultiMedia5",
+ .cpu_dai_name = "MultiMedia5",
+ .platform_name = "msm-pcm-dsp.1",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ /* this dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA5,
+ },
+ /* LSM FE */
+ {/* hw:x,14 */
+ .name = "Listen 1 Audio Service",
+ .stream_name = "Listen 1 Audio Service",
+ .cpu_dai_name = "LSM1",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM1,
+ },
+ {/* hw:x,15 */
+ .name = MSM_DAILINK_NAME(Compress2),
+ .stream_name = "Compress2",
+ .cpu_dai_name = "MultiMedia7",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA7,
+ },
+ {/* hw:x,16 */
+ .name = MSM_DAILINK_NAME(Compress3),
+ .stream_name = "Compress3",
+ .cpu_dai_name = "MultiMedia10",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA10,
+ },
+ {/* hw:x,17 */
+ .name = MSM_DAILINK_NAME(ULL_NOIRQ),
+ .stream_name = "MM_NOIRQ",
+ .cpu_dai_name = "MultiMedia8",
+ .platform_name = "msm-pcm-dsp-noirq",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
+ },
+ {/* hw:x,18 */
+ .name = "HDMI_RX_HOSTLESS",
+ .stream_name = "HDMI_RX_HOSTLESS",
+ .cpu_dai_name = "HDMI_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,19 */
+ .name = "VoiceMMode2",
+ .stream_name = "VoiceMMode2",
+ .cpu_dai_name = "VoiceMMode2",
+ .platform_name = "msm-pcm-voice",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_VOICEMMODE2,
+ },
+ {/* hw:x,20 */
+ .name = "Listen 2 Audio Service",
+ .stream_name = "Listen 2 Audio Service",
+ .cpu_dai_name = "LSM2",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM2,
+ },
+ {/* hw:x,21 */
+ .name = "Listen 3 Audio Service",
+ .stream_name = "Listen 3 Audio Service",
+ .cpu_dai_name = "LSM3",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM3,
+ },
+ {/* hw:x,22 */
+ .name = "Listen 4 Audio Service",
+ .stream_name = "Listen 4 Audio Service",
+ .cpu_dai_name = "LSM4",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM4,
+ },
+ {/* hw:x,23 */
+ .name = "Listen 5 Audio Service",
+ .stream_name = "Listen 5 Audio Service",
+ .cpu_dai_name = "LSM5",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM5,
+ },
+ {/* hw:x,24 */
+ .name = "Listen 6 Audio Service",
+ .stream_name = "Listen 6 Audio Service",
+ .cpu_dai_name = "LSM6",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM6
+ },
+ {/* hw:x,25 */
+ .name = "Listen 7 Audio Service",
+ .stream_name = "Listen 7 Audio Service",
+ .cpu_dai_name = "LSM7",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM7,
+ },
+ {/* hw:x,26 */
+ .name = "Listen 8 Audio Service",
+ .stream_name = "Listen 8 Audio Service",
+ .cpu_dai_name = "LSM8",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM8,
+ },
+ {/* hw:x,27 */
+ .name = MSM_DAILINK_NAME(Media9),
+ .stream_name = "MultiMedia9",
+ .cpu_dai_name = "MultiMedia9",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA9,
+ },
+ {/* hw:x,28 */
+ .name = MSM_DAILINK_NAME(Compress4),
+ .stream_name = "Compress4",
+ .cpu_dai_name = "MultiMedia11",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA11,
+ },
+ {/* hw:x,29 */
+ .name = MSM_DAILINK_NAME(Compress5),
+ .stream_name = "Compress5",
+ .cpu_dai_name = "MultiMedia12",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA12,
+ },
+ {/* hw:x,30 */
+ .name = MSM_DAILINK_NAME(Compress6),
+ .stream_name = "Compress6",
+ .cpu_dai_name = "MultiMedia13",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA13,
+ },
+ {/* hw:x,31 */
+ .name = MSM_DAILINK_NAME(Compress7),
+ .stream_name = "Compress7",
+ .cpu_dai_name = "MultiMedia14",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA14,
+ },
+ {/* hw:x,32 */
+ .name = MSM_DAILINK_NAME(Compress8),
+ .stream_name = "Compress8",
+ .cpu_dai_name = "MultiMedia15",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA15,
+ },
+ {/* hw:x,33 */
+ .name = MSM_DAILINK_NAME(Compress9),
+ .stream_name = "Compress9",
+ .cpu_dai_name = "MultiMedia16",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dai link has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA16,
+ },
+ {/* hw:x,34 */
+ .name = "SLIMBUS_8 Hostless",
+ .stream_name = "SLIMBUS8_HOSTLESS Capture",
+ .cpu_dai_name = "SLIMBUS8_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,35 */
+ .name = LPASS_BE_INT5_MI2S_TX,
+ .stream_name = "INT5_mi2s Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.12",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "msm_swr_codec",
+ .codec_dai_name = "msm_swr_vifeedback",
+ .be_id = MSM_BACKEND_DAI_INT5_MI2S_TX,
+ .be_hw_params_fixup = int_mi2s_be_hw_params_fixup,
+ .ops = &msm_swr_mi2s_be_ops,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .dpcm_capture = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {/* hw:x,36 */
+ .name = "Primary MI2S_RX Hostless",
+ .stream_name = "Primary MI2S_RX Hostless",
+ .cpu_dai_name = "PRI_MI2S_RX_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dailink has playback support */
+ .ignore_pmdown_time = 1,
+ /* This dainlink has MI2S support */
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,37 */
+ .name = "Secondary MI2S_RX Hostless",
+ .stream_name = "Secondary MI2S_RX Hostless",
+ .cpu_dai_name = "SEC_MI2S_RX_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dailink has playback support */
+ .ignore_pmdown_time = 1,
+ /* This dainlink has MI2S support */
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,38 */
+ .name = "Tertiary MI2S_RX Hostless",
+ .stream_name = "Tertiary MI2S_RX Hostless",
+ .cpu_dai_name = "TERT_MI2S_RX_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dailink has playback support */
+ .ignore_pmdown_time = 1,
+ /* This dainlink has MI2S support */
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {/* hw:x,39 */
+ .name = "INT0 MI2S_RX Hostless",
+ .stream_name = "INT0 MI2S_RX Hostless",
+ .cpu_dai_name = "INT0_MI2S_RX_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dailink has playback support */
+ .ignore_pmdown_time = 1,
+ /* This dainlink has MI2S support */
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ /* Backend I2S DAI Links */
+ {
+ .name = LPASS_BE_INT0_MI2S_RX,
+ .stream_name = "INT0 MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.7",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "cajon_codec",
+ .codec_dai_name = "msm8x16_wcd_i2s_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_PREPARE |
+ ASYNC_DPCM_SND_SOC_HW_PARAMS,
+ .be_id = MSM_BACKEND_DAI_INT0_MI2S_RX,
+ .init = &msm_audrx_init,
+ .be_hw_params_fixup = int_mi2s_be_hw_params_fixup,
+ .ops = &msm_int_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_INT4_MI2S_RX,
+ .stream_name = "INT4 MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.11",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm_swr_codec",
+ .codec_dai_name = "msm_swr_i2s_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_INT4_MI2S_RX,
+ .init = &msm_swr_audrx_init,
+ .be_hw_params_fixup = int_mi2s_be_hw_params_fixup,
+ .ops = &msm_swr_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_INT2_MI2S_TX,
+ .stream_name = "INT2 MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.9",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "cajon_codec",
+ .codec_dai_name = "msm8x16_wcd_i2s_tx2",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_PREPARE |
+ ASYNC_DPCM_SND_SOC_HW_PARAMS,
+ .be_id = MSM_BACKEND_DAI_INT2_MI2S_TX,
+ .be_hw_params_fixup = int_mi2s_be_hw_params_fixup,
+ .ops = &msm_int_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_INT3_MI2S_TX,
+ .stream_name = "INT3 MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.10",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "cajon_codec",
+ .codec_dai_name = "msm8x16_wcd_i2s_tx1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .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 = int_mi2s_be_hw_params_fixup,
+ .ops = &msm_int_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_AFE_PCM_RX,
+ .stream_name = "AFE Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.224",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_AFE_PCM_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_AFE_PCM_TX,
+ .stream_name = "AFE Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.225",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_AFE_PCM_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Incall Record Uplink BACK END DAI Link */
+ {
+ .name = LPASS_BE_INCALL_RECORD_TX,
+ .stream_name = "Voice Uplink Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.32772",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_INCALL_RECORD_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Incall Record Downlink BACK END DAI Link */
+ {
+ .name = LPASS_BE_INCALL_RECORD_RX,
+ .stream_name = "Voice Downlink Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.32771",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_INCALL_RECORD_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Incall Music BACK END DAI Link */
+ {
+ .name = LPASS_BE_VOICE_PLAYBACK_TX,
+ .stream_name = "Voice Farend Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.32773",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Incall Music 2 BACK END DAI Link */
+ {
+ .name = LPASS_BE_VOICE2_PLAYBACK_TX,
+ .stream_name = "Voice2 Farend Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.32770",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_USB_AUDIO_RX,
+ .stream_name = "USB Audio Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.28672",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_USB_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_USB_AUDIO_TX,
+ .stream_name = "USB Audio Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.28673",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_USB_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_TDM_RX_0,
+ .stream_name = "Primary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36864",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_TDM_TX_0,
+ .stream_name = "Primary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36865",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_TDM_RX_0,
+ .stream_name = "Secondary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36880",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_TDM_TX_0,
+ .stream_name = "Secondary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36881",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_TDM_RX_0,
+ .stream_name = "Tertiary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36896",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_TDM_TX_0,
+ .stream_name = "Tertiary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36897",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_TDM_RX_0,
+ .stream_name = "Quaternary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36912",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_TDM_TX_0,
+ .stream_name = "Quaternary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36913",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_0,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+};
+
+static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = {
+ {
+ .name = LPASS_BE_PRI_MI2S_RX,
+ .stream_name = "Primary MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.0",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_MI2S_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_MI2S_TX,
+ .stream_name = "Primary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.0",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_MI2S_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_MI2S_RX,
+ .stream_name = "Secondary MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_MI2S_TX,
+ .stream_name = "Secondary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_MI2S_RX,
+ .stream_name = "Tertiary MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.2",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_MI2S_TX,
+ .stream_name = "Tertiary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.2",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_RX,
+ .stream_name = "Quaternary MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_TX,
+ .stream_name = "Quaternary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+};
+
+static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = {
+ /* Primary AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_AUXPCM_RX,
+ .stream_name = "AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_AUXPCM_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+ {
+ .name = LPASS_BE_AUXPCM_TX,
+ .stream_name = "AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_AUXPCM_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+ /* Secondary AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_SEC_AUXPCM_RX,
+ .stream_name = "Sec AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.2",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+ {
+ .name = LPASS_BE_SEC_AUXPCM_TX,
+ .stream_name = "Sec AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.2",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+ /* Tertiary AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_TERT_AUXPCM_RX,
+ .stream_name = "Tert AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+ {
+ .name = LPASS_BE_TERT_AUXPCM_TX,
+ .stream_name = "Tert AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+ /* Quaternary AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_QUAT_AUXPCM_RX,
+ .stream_name = "Quat AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.4",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+ {
+ .name = LPASS_BE_QUAT_AUXPCM_TX,
+ .stream_name = "Quat AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.4",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX,
+ .be_hw_params_fixup = msm_common_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .ops = &msm_aux_pcm_be_ops,
+ },
+};
+
+
+static struct snd_soc_dai_link msm_wcn_be_dai_links[] = {
+ {
+ .name = LPASS_BE_SLIMBUS_7_RX,
+ .stream_name = "Slimbus7 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16398",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "btfmslim_slave",
+ /* BT codec driver determines capabilities based on
+ * dai name, bt codecdai name should always contains
+ * supported usecase information
+ */
+ .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_7_RX,
+ .be_hw_params_fixup = msm_btfm_be_hw_params_fixup,
+ .ops = &msm_wcn_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_7_TX,
+ .stream_name = "Slimbus7 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16399",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "btfmslim_slave",
+ .codec_dai_name = "btfm_bt_sco_slim_tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_7_TX,
+ .be_hw_params_fixup = msm_btfm_be_hw_params_fixup,
+ .ops = &msm_wcn_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_8_TX,
+ .stream_name = "Slimbus8 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16401",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "btfmslim_slave",
+ .codec_dai_name = "btfm_fm_slim_tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_8_TX,
+ .be_hw_params_fixup = msm_btfm_be_hw_params_fixup,
+ .init = &msm_wcn_init,
+ .ops = &msm_wcn_ops,
+ .ignore_suspend = 1,
+ },
+};
+
+static struct snd_soc_dai_link msm_int_dai_links[
+ARRAY_SIZE(msm_int_dai) +
+ARRAY_SIZE(msm_mi2s_be_dai_links) +
+ARRAY_SIZE(msm_auxpcm_be_dai_links)+
+ARRAY_SIZE(msm_wcn_be_dai_links)];
+
+static struct snd_soc_card msmfalcon_card = {
+ /* snd_soc_card_msmfalcon */
+ .name = "msmfalcon-snd-card",
+ .dai_link = msm_int_dai,
+ .num_links = ARRAY_SIZE(msm_int_dai),
+};
+
+static void msm_disable_int_mclk0(struct work_struct *work)
+{
+ struct msm_asoc_mach_data *pdata = NULL;
+ struct delayed_work *dwork;
+ int ret = 0;
+
+ dwork = to_delayed_work(work);
+ pdata = container_of(dwork, struct msm_asoc_mach_data,
+ disable_int_mclk0_work);
+ mutex_lock(&pdata->cdc_int_mclk0_mutex);
+ pr_debug("%s: mclk_enabled %d mclk_rsc_ref %d\n", __func__,
+ atomic_read(&pdata->int_mclk0_enabled),
+ atomic_read(&pdata->int_mclk0_rsc_ref));
+
+ if (atomic_read(&pdata->int_mclk0_enabled) == true
+ && atomic_read(&pdata->int_mclk0_rsc_ref) == 0) {
+ pr_debug("Disable the mclk\n");
+ pdata->digital_cdc_core_clk.enable = 0;
+ ret = afe_set_lpass_clock_v2(
+ AFE_PORT_ID_INT0_MI2S_RX,
+ &pdata->digital_cdc_core_clk);
+ if (ret < 0)
+ pr_err("%s failed to disable the CCLK\n", __func__);
+ atomic_set(&pdata->int_mclk0_enabled, false);
+ }
+ mutex_unlock(&pdata->cdc_int_mclk0_mutex);
+}
+
+static void msm_int_dt_parse_cap_info(struct platform_device *pdev,
+ struct msm_asoc_mach_data *pdata)
+{
+ const char *ext1_cap = "qcom,msm-micbias1-ext-cap";
+ const char *ext2_cap = "qcom,msm-micbias2-ext-cap";
+
+ pdata->micbias1_cap_mode =
+ (of_property_read_bool(pdev->dev.of_node, ext1_cap) ?
+ MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);
+
+ pdata->micbias2_cap_mode =
+ (of_property_read_bool(pdev->dev.of_node, ext2_cap) ?
+ MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);
+}
+
+static struct snd_soc_card *msm_int_populate_sndcard_dailinks(
+ struct device *dev)
+{
+ struct snd_soc_card *card = &msmfalcon_card;
+ struct snd_soc_dai_link *dailink;
+ int len1;
+
+ card->name = dev_name(dev);
+ len1 = ARRAY_SIZE(msm_int_dai);
+ memcpy(msm_int_dai_links, msm_int_dai, sizeof(msm_int_dai));
+ dailink = msm_int_dai_links;
+ if (of_property_read_bool(dev->of_node,
+ "qcom,mi2s-audio-intf")) {
+ memcpy(dailink + len1,
+ msm_mi2s_be_dai_links,
+ sizeof(msm_mi2s_be_dai_links));
+ len1 += ARRAY_SIZE(msm_mi2s_be_dai_links);
+ }
+ if (of_property_read_bool(dev->of_node,
+ "qcom,auxpcm-audio-intf")) {
+ memcpy(dailink + len1,
+ msm_auxpcm_be_dai_links,
+ sizeof(msm_auxpcm_be_dai_links));
+ len1 += ARRAY_SIZE(msm_auxpcm_be_dai_links);
+ }
+ if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) {
+ dev_dbg(dev, "%s(): WCN BTFM support present\n",
+ __func__);
+ memcpy(dailink + len1,
+ msm_wcn_be_dai_links,
+ sizeof(msm_wcn_be_dai_links));
+ len1 += ARRAY_SIZE(msm_wcn_be_dai_links);
+ }
+ card->dai_link = dailink;
+ card->num_links = len1;
+ return card;
+}
+
+static int msm_internal_init(struct platform_device *pdev,
+ struct msm_asoc_mach_data *pdata,
+ struct snd_soc_card *card)
+{
+ const char *type = NULL;
+ const char *hs_micbias_type = "qcom,msm-hs-micbias-type";
+ int ret;
+
+ ret = is_ext_spk_gpio_support(pdev, pdata);
+ if (ret < 0)
+ dev_dbg(&pdev->dev,
+ "%s: doesn't support external speaker pa\n",
+ __func__);
+
+ ret = of_property_read_string(pdev->dev.of_node,
+ hs_micbias_type, &type);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: missing %s in dt node\n",
+ __func__, hs_micbias_type);
+ goto err;
+ }
+ if (!strcmp(type, "external")) {
+ dev_dbg(&pdev->dev, "Headset is using external micbias\n");
+ mbhc_cfg_ptr->hs_ext_micbias = true;
+ } else {
+ dev_dbg(&pdev->dev, "Headset is using internal micbias\n");
+ mbhc_cfg_ptr->hs_ext_micbias = false;
+ }
+
+ /* initialize the int_mclk0 */
+ pdata->digital_cdc_core_clk.clk_set_minor_version =
+ AFE_API_VERSION_I2S_CONFIG;
+ pdata->digital_cdc_core_clk.clk_id =
+ Q6AFE_LPASS_CLK_ID_INT_MCLK_0;
+ pdata->digital_cdc_core_clk.clk_freq_in_hz =
+ pdata->mclk_freq;
+ pdata->digital_cdc_core_clk.clk_attri =
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO;
+ pdata->digital_cdc_core_clk.clk_root =
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT;
+ pdata->digital_cdc_core_clk.enable = 1;
+
+ /* Initialize loopback mode to false */
+ pdata->lb_mode = false;
+
+ msm_int_dt_parse_cap_info(pdev, pdata);
+
+ card->dev = &pdev->dev;
+ platform_set_drvdata(pdev, card);
+ snd_soc_card_set_drvdata(card, pdata);
+ ret = snd_soc_of_parse_card_name(card, "qcom,model");
+ if (ret)
+ goto err;
+ /* initialize timer */
+ INIT_DELAYED_WORK(&pdata->disable_int_mclk0_work,
+ msm_disable_int_mclk0);
+ mutex_init(&pdata->cdc_int_mclk0_mutex);
+ atomic_set(&pdata->int_mclk0_rsc_ref, 0);
+ atomic_set(&pdata->int_mclk0_enabled, false);
+
+ dev_info(&pdev->dev, "%s: default codec configured\n", __func__);
+
+ return 0;
+err:
+ return ret;
+}
+
+/**
+ * msm_int_cdc_init - internal codec machine specific init.
+ *
+ * @pdev: platform device handle
+ * @pdata: private data of machine driver
+ * @card: sound card pointer reference
+ * @mbhc_cfg: MBHC config reference
+ *
+ * Returns 0.
+ */
+int msm_int_cdc_init(struct platform_device *pdev,
+ struct msm_asoc_mach_data *pdata,
+ struct snd_soc_card **card,
+ struct wcd_mbhc_config *mbhc_cfg)
+{
+ mbhc_cfg_ptr = mbhc_cfg;
+
+ *card = msm_int_populate_sndcard_dailinks(&pdev->dev);
+ msm_internal_init(pdev, pdata, *card);
+ return 0;
+}
+EXPORT_SYMBOL(msm_int_cdc_init);
diff --git a/sound/soc/msm/msmfalcon-internal.h b/sound/soc/msm/msmfalcon-internal.h
new file mode 100644
index 000000000000..e5e3e7c66246
--- /dev/null
+++ b/sound/soc/msm/msmfalcon-internal.h
@@ -0,0 +1,32 @@
+/* Copyright (c) 2016, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSMFALCON_INTERNAL
+#define __MSMFALCON_INTERNAL
+
+#include <sound/soc.h>
+
+#ifdef CONFIG_SND_SOC_INT_CODEC
+int msm_int_cdc_init(struct platform_device *pdev,
+ struct msm_asoc_mach_data *pdata,
+ struct snd_soc_card **card,
+ struct wcd_mbhc_config *mbhc_cfg);
+#else
+int msm_int_cdc_init(struct platform_device *pdev,
+ struct msm_asoc_mach_data *pdata,
+ struct snd_soc_card **card,
+ struct wcd_mbhc_config *mbhc_cfg)
+{
+ return 0;
+}
+#endif
+#endif
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index 770bd12eb501..a2cd6c6f98db 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -2779,10 +2779,10 @@ static int msm_compr_app_type_cfg_put(struct snd_kcontrol *kcontrol,
acdb_dev_id = ucontrol->value.integer.value[1];
if (0 != ucontrol->value.integer.value[2])
sample_rate = ucontrol->value.integer.value[2];
- pr_debug("%s: app_type- %d acdb_dev_id- %d sample_rate- %d\n",
- __func__, app_type, acdb_dev_id, sample_rate);
+ 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_RX);
msm_pcm_routing_reg_stream_app_type_cfg(fe_id, app_type,
- acdb_dev_id, sample_rate);
+ acdb_dev_id, sample_rate, SESSION_TYPE_RX);
return 0;
}
@@ -2804,8 +2804,8 @@ static int msm_compr_app_type_cfg_get(struct snd_kcontrol *kcontrol,
goto done;
}
- ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, &app_type,
- &acdb_dev_id, &sample_rate);
+ ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, SESSION_TYPE_RX,
+ &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);
@@ -2815,8 +2815,9 @@ static int msm_compr_app_type_cfg_get(struct snd_kcontrol *kcontrol,
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, app_type %d, acdb_dev_id %d, sample_rate %d\n",
- __func__, fe_id, app_type, acdb_dev_id, 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_RX,
+ app_type, acdb_dev_id, sample_rate);
done:
return ret;
}
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index 7eb4a10b83c7..718f7017342b 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -3481,12 +3481,32 @@ static int msm_mi2s_get_port_id(u32 mi2s_id, int stream, u16 *port_id)
case MSM_QUIN_MI2S:
*port_id = AFE_PORT_ID_QUINARY_MI2S_RX;
break;
- break;
+ case MSM_INT0_MI2S:
+ *port_id = AFE_PORT_ID_INT0_MI2S_RX;
+ break;
+ case MSM_INT1_MI2S:
+ *port_id = AFE_PORT_ID_INT1_MI2S_RX;
+ break;
+ case MSM_INT2_MI2S:
+ *port_id = AFE_PORT_ID_INT2_MI2S_RX;
+ break;
+ case MSM_INT3_MI2S:
+ *port_id = AFE_PORT_ID_INT3_MI2S_RX;
+ break;
+ case MSM_INT4_MI2S:
+ *port_id = AFE_PORT_ID_INT4_MI2S_RX;
+ break;
+ case MSM_INT5_MI2S:
+ *port_id = AFE_PORT_ID_INT5_MI2S_RX;
+ break;
+ case MSM_INT6_MI2S:
+ *port_id = AFE_PORT_ID_INT6_MI2S_RX;
+ break;
default:
pr_err("%s: playback err id 0x%x\n",
__func__, mi2s_id);
ret = -1;
- break;
+ break;
}
break;
case SNDRV_PCM_STREAM_CAPTURE:
@@ -3509,10 +3529,31 @@ static int msm_mi2s_get_port_id(u32 mi2s_id, int stream, u16 *port_id)
case MSM_SENARY_MI2S:
*port_id = AFE_PORT_ID_SENARY_MI2S_TX;
break;
+ case MSM_INT0_MI2S:
+ *port_id = AFE_PORT_ID_INT0_MI2S_TX;
+ break;
+ case MSM_INT1_MI2S:
+ *port_id = AFE_PORT_ID_INT1_MI2S_TX;
+ break;
+ case MSM_INT2_MI2S:
+ *port_id = AFE_PORT_ID_INT2_MI2S_TX;
+ break;
+ case MSM_INT3_MI2S:
+ *port_id = AFE_PORT_ID_INT3_MI2S_TX;
+ break;
+ case MSM_INT4_MI2S:
+ *port_id = AFE_PORT_ID_INT4_MI2S_TX;
+ break;
+ case MSM_INT5_MI2S:
+ *port_id = AFE_PORT_ID_INT5_MI2S_TX;
+ break;
+ case MSM_INT6_MI2S:
+ *port_id = AFE_PORT_ID_INT6_MI2S_TX;
+ break;
default:
pr_err("%s: capture err id 0x%x\n", __func__, mi2s_id);
ret = -1;
- break;
+ break;
}
break;
default:
@@ -3968,6 +4009,188 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = {
.probe = msm_dai_q6_dai_mi2s_probe,
.remove = msm_dai_q6_dai_mi2s_remove,
},
+ {
+ .playback = {
+ .stream_name = "INT0 MI2S Playback",
+ .aif_name = "INT0_MI2S_RX",
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_44100,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .capture = {
+ .stream_name = "INT0 MI2S Capture",
+ .aif_name = "INT0_MI2S_TX",
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_dai_q6_mi2s_ops,
+ .id = MSM_INT0_MI2S,
+ .probe = msm_dai_q6_dai_mi2s_probe,
+ .remove = msm_dai_q6_dai_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "INT1 MI2S Playback",
+ .aif_name = "INT1_MI2S_RX",
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .capture = {
+ .stream_name = "INT1 MI2S Capture",
+ .aif_name = "INT1_MI2S_TX",
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_dai_q6_mi2s_ops,
+ .id = MSM_INT1_MI2S,
+ .probe = msm_dai_q6_dai_mi2s_probe,
+ .remove = msm_dai_q6_dai_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "INT2 MI2S Playback",
+ .aif_name = "INT2_MI2S_RX",
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .capture = {
+ .stream_name = "INT2 MI2S Capture",
+ .aif_name = "INT2_MI2S_TX",
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_dai_q6_mi2s_ops,
+ .id = MSM_INT2_MI2S,
+ .probe = msm_dai_q6_dai_mi2s_probe,
+ .remove = msm_dai_q6_dai_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "INT3 MI2S Playback",
+ .aif_name = "INT3_MI2S_RX",
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .capture = {
+ .stream_name = "INT3 MI2S Capture",
+ .aif_name = "INT3_MI2S_TX",
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_dai_q6_mi2s_ops,
+ .id = MSM_INT3_MI2S,
+ .probe = msm_dai_q6_dai_mi2s_probe,
+ .remove = msm_dai_q6_dai_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "INT4 MI2S Playback",
+ .aif_name = "INT4_MI2S_RX",
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .capture = {
+ .stream_name = "INT4 MI2S Capture",
+ .aif_name = "INT4_MI2S_TX",
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_dai_q6_mi2s_ops,
+ .id = MSM_INT4_MI2S,
+ .probe = msm_dai_q6_dai_mi2s_probe,
+ .remove = msm_dai_q6_dai_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "INT5 MI2S Playback",
+ .aif_name = "INT5_MI2S_RX",
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .capture = {
+ .stream_name = "INT5 MI2S Capture",
+ .aif_name = "INT5_MI2S_TX",
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_dai_q6_mi2s_ops,
+ .id = MSM_INT5_MI2S,
+ .probe = msm_dai_q6_dai_mi2s_probe,
+ .remove = msm_dai_q6_dai_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "INT6 MI2S Playback",
+ .aif_name = "INT6_MI2S_RX",
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .capture = {
+ .stream_name = "INT6 MI2S Capture",
+ .aif_name = "INT6_MI2S_TX",
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_dai_q6_mi2s_ops,
+ .id = MSM_INT6_MI2S,
+ .probe = msm_dai_q6_dai_mi2s_probe,
+ .remove = msm_dai_q6_dai_mi2s_remove,
+ },
};
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
index ff7cf5812c0c..82458275b892 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
@@ -516,7 +516,7 @@ exit:
return rc;
}
-static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd)
+static int msm_pcm_add_volume_controls(struct snd_soc_pcm_runtime *rtd)
{
struct snd_pcm *pcm = rtd->pcm->streams[0].pcm;
struct snd_pcm_volume *volume_info;
@@ -537,6 +537,192 @@ static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd)
return 0;
}
+static int msm_pcm_playback_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 = 48000;
+
+ pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
+ if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+ 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];
+ if (ucontrol->value.integer.value[2] != 0)
+ 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_RX);
+ msm_pcm_routing_reg_stream_app_type_cfg(fe_id, app_type,
+ acdb_dev_id, sample_rate, SESSION_TYPE_RX);
+
+ return 0;
+}
+
+static int msm_pcm_playback_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_MAX) {
+ pr_err("%s: Received out of bounds fe_id %llu\n",
+ __func__, fe_id);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, SESSION_TYPE_RX,
+ &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_RX,
+ app_type, acdb_dev_id, sample_rate);
+done:
+ return ret;
+}
+
+static int msm_pcm_capture_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 = 48000;
+
+ pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
+ if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+ 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];
+ if (ucontrol->value.integer.value[2] != 0)
+ 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_pcm_capture_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_MAX) {
+ pr_err("%s: Received out of bounds fe_id %llu\n",
+ __func__, fe_id);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ 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_pcm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_pcm *pcm = rtd->pcm->streams[0].pcm;
+ struct snd_pcm_usr *app_type_info;
+ struct snd_kcontrol *kctl;
+ const char *playback_mixer_ctl_name = "Audio Stream";
+ const char *capture_mixer_ctl_name = "Audio Stream Capture";
+ const char *deviceNo = "NN";
+ const char *suffix = "App Type Cfg";
+ int ctl_len, ret = 0;
+
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
+ ctl_len = strlen(playback_mixer_ctl_name) + 1 +
+ strlen(deviceNo) + 1 + strlen(suffix) + 1;
+ pr_debug("%s: Playback app type cntrl add\n", __func__);
+ ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ NULL, 1, ctl_len, rtd->dai_link->be_id,
+ &app_type_info);
+ if (ret < 0)
+ return ret;
+ kctl = app_type_info->kctl;
+ snprintf(kctl->id.name, ctl_len, "%s %d %s",
+ playback_mixer_ctl_name, rtd->pcm->device, suffix);
+ kctl->put = msm_pcm_playback_app_type_cfg_ctl_put;
+ kctl->get = msm_pcm_playback_app_type_cfg_ctl_get;
+ }
+
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
+ ctl_len = strlen(capture_mixer_ctl_name) + 1 +
+ strlen(deviceNo) + 1 + strlen(suffix) + 1;
+ pr_debug("%s: Capture 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)
+ return ret;
+ kctl = app_type_info->kctl;
+ snprintf(kctl->id.name, ctl_len, "%s %d %s",
+ capture_mixer_ctl_name, rtd->pcm->device, suffix);
+ kctl->put = msm_pcm_capture_app_type_cfg_ctl_put;
+ kctl->get = msm_pcm_capture_app_type_cfg_ctl_get;
+ }
+
+ return 0;
+}
+
+static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd)
+{
+ int ret = 0;
+
+ pr_debug("%s\n", __func__);
+ ret = msm_pcm_add_volume_controls(rtd);
+ if (ret)
+ pr_err("%s: pcm add volume controls failed:%d\n",
+ __func__, ret);
+ ret = msm_pcm_add_app_type_controls(rtd);
+ if (ret)
+ pr_err("%s: pcm add app type controls failed:%d\n",
+ __func__, ret);
+ return ret;
+}
+
static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index c5baf0e63732..920e7324f14a 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -1178,7 +1178,7 @@ static int msm_pcm_add_chmap_controls(struct snd_soc_pcm_runtime *rtd)
return 0;
}
-static int msm_pcm_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
+static int msm_pcm_playback_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
u64 fe_id = kcontrol->private_value;
@@ -1197,15 +1197,15 @@ static int msm_pcm_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
acdb_dev_id = ucontrol->value.integer.value[1];
if (0 != ucontrol->value.integer.value[2])
sample_rate = ucontrol->value.integer.value[2];
- pr_debug("%s: app_type- %d acdb_dev_id- %d sample_rate- %d\n",
- __func__, app_type, acdb_dev_id, sample_rate);
+ 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_RX);
msm_pcm_routing_reg_stream_app_type_cfg(fe_id, app_type,
- acdb_dev_id, sample_rate);
+ acdb_dev_id, sample_rate, SESSION_TYPE_RX);
return 0;
}
-static int msm_pcm_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol,
+static int msm_pcm_playback_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
u64 fe_id = kcontrol->private_value;
@@ -1222,8 +1222,8 @@ static int msm_pcm_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol,
goto done;
}
- ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, &app_type,
- &acdb_dev_id, &sample_rate);
+ ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, SESSION_TYPE_RX,
+ &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);
@@ -1233,8 +1233,71 @@ static int msm_pcm_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol,
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, app_type %d, acdb_dev_id %d, sample_rate %d\n",
- __func__, fe_id, app_type, acdb_dev_id, 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_RX,
+ app_type, acdb_dev_id, sample_rate);
+done:
+ return ret;
+}
+
+static int msm_pcm_capture_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 = 48000;
+
+ pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
+ if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+ 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];
+ if (ucontrol->value.integer.value[2] != 0)
+ 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_pcm_capture_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_MAX) {
+ pr_err("%s: Received out of bounds fe_id %llu\n",
+ __func__, fe_id);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ 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;
}
@@ -1244,27 +1307,49 @@ static int msm_pcm_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 = "Audio Stream";
+ const char *playback_mixer_ctl_name = "Audio Stream";
+ const char *capture_mixer_ctl_name = "Audio Stream Capture";
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, App type cntrl add\n", __func__);
- ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- NULL, 1, ctl_len, rtd->dai_link->be_id,
- &app_type_info);
- if (ret < 0) {
- pr_err("%s, app type cntrl add failed:%d\n", __func__, ret);
- return ret;
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
+ ctl_len = strlen(playback_mixer_ctl_name) + 1 +
+ strlen(deviceNo) + 1 + strlen(suffix) + 1;
+ pr_debug("%s: Playback app type cntrl add\n", __func__);
+ ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ NULL, 1, ctl_len, rtd->dai_link->be_id,
+ &app_type_info);
+ if (ret < 0) {
+ pr_err("%s: playback 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",
+ playback_mixer_ctl_name, rtd->pcm->device, suffix);
+ kctl->put = msm_pcm_playback_app_type_cfg_ctl_put;
+ kctl->get = msm_pcm_playback_app_type_cfg_ctl_get;
+ }
+
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
+ ctl_len = strlen(capture_mixer_ctl_name) + 1 +
+ strlen(deviceNo) + 1 + strlen(suffix) + 1;
+ pr_debug("%s: Capture 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: capture 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",
+ capture_mixer_ctl_name, rtd->pcm->device, suffix);
+ kctl->put = msm_pcm_capture_app_type_cfg_ctl_put;
+ kctl->get = msm_pcm_capture_app_type_cfg_ctl_get;
}
- kctl = app_type_info->kctl;
- snprintf(kctl->id.name, ctl_len, "%s %d %s", mixer_ctl_name,
- rtd->pcm->device, suffix);
- kctl = app_type_info->kctl;
- kctl->put = msm_pcm_app_type_cfg_ctl_put;
- kctl->get = msm_pcm_app_type_cfg_ctl_get;
return 0;
}
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 13d4ba27d990..9681330be33b 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -466,6 +466,34 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
LPASS_BE_QUAT_AUXPCM_RX},
{ 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,
+ LPASS_BE_INT0_MI2S_RX},
+ { 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,
+ LPASS_BE_INT1_MI2S_RX},
+ { 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,
+ LPASS_BE_INT2_MI2S_RX},
+ { 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,
+ LPASS_BE_INT3_MI2S_RX},
+ { 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,
+ LPASS_BE_INT4_MI2S_RX},
+ { 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,
+ LPASS_BE_INT5_MI2S_RX},
+ { 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,
+ LPASS_BE_INT6_MI2S_RX},
+ { AFE_PORT_ID_INT6_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ LPASS_BE_INT6_MI2S_TX},
};
/* Track ASM playback & capture sessions of DAI */
@@ -525,7 +553,7 @@ static unsigned long session_copp_map[MSM_FRONTEND_DAI_MM_SIZE][2]
[MSM_BACKEND_DAI_MAX];
static struct msm_pcm_routing_app_type_data app_type_cfg[MAX_APP_TYPES];
static struct msm_pcm_stream_app_type_cfg
- fe_dai_app_type_cfg[MSM_FRONTEND_DAI_MM_SIZE];
+ fe_dai_app_type_cfg[MSM_FRONTEND_DAI_MM_SIZE][2];
/* The caller of this should aqcuire routing lock */
void msm_pcm_routing_get_bedai_info(int be_idx,
@@ -569,34 +597,43 @@ static int msm_pcm_routing_get_app_type_idx(int app_type)
}
void msm_pcm_routing_reg_stream_app_type_cfg(int fedai_id, int app_type,
- int acdb_dev_id, int sample_rate)
+ int acdb_dev_id, int sample_rate, int session_type)
{
- pr_debug("%s: fedai_id %d, app_type %d, sample_rate %d\n",
- __func__, fedai_id, app_type, sample_rate);
+ 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) {
pr_err("%s: Invalid machine driver ID %d\n",
__func__, fedai_id);
return;
}
- fe_dai_app_type_cfg[fedai_id].app_type = app_type;
- fe_dai_app_type_cfg[fedai_id].acdb_dev_id = acdb_dev_id;
- fe_dai_app_type_cfg[fedai_id].sample_rate = sample_rate;
+ if (session_type != SESSION_TYPE_RX &&
+ session_type != SESSION_TYPE_TX) {
+ pr_err("%s: Invalid session type %d\n",
+ __func__, session_type);
+ return;
+ }
+ fe_dai_app_type_cfg[fedai_id][session_type].app_type = app_type;
+ fe_dai_app_type_cfg[fedai_id][session_type].acdb_dev_id = acdb_dev_id;
+ fe_dai_app_type_cfg[fedai_id][session_type].sample_rate = sample_rate;
}
/**
* msm_pcm_routing_get_stream_app_type_cfg
*
- * Receives fedai_id and populates app_type, acdb_dev_id, &
+ * Receives fedai_id, session_type and populates app_type, acdb_dev_id, &
* sample rate. Returns 0 on success. On failure returns
* -EINVAL and does not alter passed values.
*
* fedai_id - Passed value, front end ID for which app type config is wanted
+ * session_type - Passed value, session type for which app type config
+ * is wanted
* app_type - Returned value, app type used by app type config
* acdb_dev_id - Returned value, ACDB device ID used by app type config
* sample_rate - Returned value, sample rate used by app type config
*/
-int msm_pcm_routing_get_stream_app_type_cfg(int fedai_id, int *app_type,
- int *acdb_dev_id, int *sample_rate)
+int msm_pcm_routing_get_stream_app_type_cfg(int fedai_id, int session_type,
+ int *app_type, int *acdb_dev_id, int *sample_rate)
{
int ret = 0;
@@ -617,13 +654,20 @@ int msm_pcm_routing_get_stream_app_type_cfg(int fedai_id, int *app_type,
__func__, fedai_id);
ret = -EINVAL;
goto done;
+ } else if (session_type != SESSION_TYPE_RX &&
+ session_type != SESSION_TYPE_TX) {
+ pr_err("%s: Invalid session type %d\n",
+ __func__, session_type);
+ ret = -EINVAL;
+ goto done;
}
- *app_type = fe_dai_app_type_cfg[fedai_id].app_type;
- *acdb_dev_id = fe_dai_app_type_cfg[fedai_id].acdb_dev_id;
- *sample_rate = fe_dai_app_type_cfg[fedai_id].sample_rate;
+ *app_type = fe_dai_app_type_cfg[fedai_id][session_type].app_type;
+ *acdb_dev_id = fe_dai_app_type_cfg[fedai_id][session_type].acdb_dev_id;
+ *sample_rate = fe_dai_app_type_cfg[fedai_id][session_type].sample_rate;
- pr_debug("%s: fedai_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n",
- __func__, fedai_id, *app_type, *acdb_dev_id, *sample_rate);
+ 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);
done:
return ret;
}
@@ -680,7 +724,8 @@ static struct cal_block_data *msm_routing_find_topology(int path,
return msm_routing_find_topology_by_path(path);
}
-static int msm_routing_get_adm_topology(int path, int fedai_id)
+static int msm_routing_get_adm_topology(int path, int fedai_id,
+ int session_type)
{
int topology = NULL_COPP_TOPOLOGY;
struct cal_block_data *cal_block = NULL;
@@ -693,11 +738,10 @@ static int msm_routing_get_adm_topology(int path, int fedai_id)
mutex_lock(&cal_data->lock);
- if (path == RX_DEVICE) {
- app_type = fe_dai_app_type_cfg[fedai_id].app_type;
- acdb_dev_id = fe_dai_app_type_cfg[fedai_id].acdb_dev_id;
- sample_rate = fe_dai_app_type_cfg[fedai_id].sample_rate;
- }
+ app_type = fe_dai_app_type_cfg[fedai_id][session_type].app_type;
+ acdb_dev_id = fe_dai_app_type_cfg[fedai_id][session_type].acdb_dev_id;
+ sample_rate = fe_dai_app_type_cfg[fedai_id][session_type].sample_rate;
+
cal_block = msm_routing_find_topology(path, app_type,
acdb_dev_id, sample_rate);
if (cal_block == NULL)
@@ -753,9 +797,12 @@ static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type,
if (num_copps) {
payload.num_copps = num_copps;
payload.session_id = fe_dai_map[fedai_id][sess_type].strm_id;
- payload.app_type = fe_dai_app_type_cfg[fedai_id].app_type;
- payload.acdb_dev_id = fe_dai_app_type_cfg[fedai_id].acdb_dev_id;
- payload.sample_rate = fe_dai_app_type_cfg[fedai_id].sample_rate;
+ payload.app_type =
+ fe_dai_app_type_cfg[fedai_id][sess_type].app_type;
+ payload.acdb_dev_id =
+ 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);
msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode);
}
@@ -863,22 +910,23 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
bit_width = msm_routing_get_bit_width(
msm_bedais[i].format);
- app_type = (stream_type == SNDRV_PCM_STREAM_PLAYBACK) ?
- fe_dai_app_type_cfg[fe_id].app_type : 0;
+ app_type =
+ fe_dai_app_type_cfg[fe_id][session_type].app_type;
if (app_type) {
app_type_idx =
msm_pcm_routing_get_app_type_idx(
app_type);
sample_rate =
- fe_dai_app_type_cfg[fe_id].sample_rate;
+ fe_dai_app_type_cfg[fe_id][session_type].sample_rate;
bit_width =
app_type_cfg[app_type_idx].bit_width;
} else {
sample_rate = msm_bedais[i].sample_rate;
}
- acdb_dev_id = fe_dai_app_type_cfg[fe_id].acdb_dev_id;
+ acdb_dev_id =
+ fe_dai_app_type_cfg[fe_id][session_type].acdb_dev_id;
topology = msm_routing_get_adm_topology(path_type,
- fe_id);
+ fe_id, session_type);
if (compr_passthr_mode == COMPRESSED_PASSTHROUGH_DSD)
topology = COMPRESS_PASSTHROUGH_NONE_TOPOLOGY;
pr_err("%s: Before adm open topology %d\n", __func__,
@@ -928,8 +976,10 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
if (num_copps) {
payload.num_copps = num_copps;
payload.session_id = fe_dai_map[fe_id][session_type].strm_id;
- payload.app_type = fe_dai_app_type_cfg[fe_id].app_type;
- payload.acdb_dev_id = fe_dai_app_type_cfg[fe_id].acdb_dev_id;
+ payload.app_type =
+ 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);
msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode);
}
@@ -1026,21 +1076,23 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
bits_per_sample = msm_routing_get_bit_width(
msm_bedais[i].format);
- app_type = (stream_type == SNDRV_PCM_STREAM_PLAYBACK) ?
- fe_dai_app_type_cfg[fedai_id].app_type : 0;
+ app_type =
+ fe_dai_app_type_cfg[fedai_id][session_type].app_type;
if (app_type) {
app_type_idx =
msm_pcm_routing_get_app_type_idx(app_type);
sample_rate =
- fe_dai_app_type_cfg[fedai_id].sample_rate;
+ fe_dai_app_type_cfg[fedai_id][session_type].
+ sample_rate;
bits_per_sample =
app_type_cfg[app_type_idx].bit_width;
} else
sample_rate = msm_bedais[i].sample_rate;
- acdb_dev_id = fe_dai_app_type_cfg[fedai_id].acdb_dev_id;
+ acdb_dev_id =
+ fe_dai_app_type_cfg[fedai_id][session_type].acdb_dev_id;
topology = msm_routing_get_adm_topology(path_type,
- fedai_id);
+ fedai_id, session_type);
copp_idx = adm_open(msm_bedais[i].port_id, path_type,
sample_rate, channels, topology,
perf_mode, bits_per_sample,
@@ -1085,9 +1137,12 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
if (num_copps) {
payload.num_copps = num_copps;
payload.session_id = fe_dai_map[fedai_id][session_type].strm_id;
- payload.app_type = fe_dai_app_type_cfg[fedai_id].app_type;
- payload.acdb_dev_id = fe_dai_app_type_cfg[fedai_id].acdb_dev_id;
- payload.sample_rate = fe_dai_app_type_cfg[fedai_id].sample_rate;
+ payload.app_type =
+ fe_dai_app_type_cfg[fedai_id][session_type].app_type;
+ payload.acdb_dev_id =
+ 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);
msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode);
}
@@ -1255,20 +1310,23 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
bits_per_sample = msm_routing_get_bit_width(
msm_bedais[reg].format);
- app_type = (session_type == SESSION_TYPE_RX) ?
- fe_dai_app_type_cfg[val].app_type : 0;
+ app_type =
+ fe_dai_app_type_cfg[val][session_type].app_type;
if (app_type) {
app_type_idx =
msm_pcm_routing_get_app_type_idx(app_type);
sample_rate =
- fe_dai_app_type_cfg[val].sample_rate;
+ fe_dai_app_type_cfg[val][session_type].
+ sample_rate;
bits_per_sample =
app_type_cfg[app_type_idx].bit_width;
} else
sample_rate = msm_bedais[reg].sample_rate;
- topology = msm_routing_get_adm_topology(path_type, val);
- acdb_dev_id = fe_dai_app_type_cfg[val].acdb_dev_id;
+ topology = msm_routing_get_adm_topology(path_type, val,
+ session_type);
+ acdb_dev_id =
+ fe_dai_app_type_cfg[val][session_type].acdb_dev_id;
copp_idx = adm_open(msm_bedais[reg].port_id, path_type,
sample_rate, channels, topology,
fdai->perf_mode, bits_per_sample,
@@ -2919,6 +2977,108 @@ static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = {
msm_routing_put_audio_mixer),
};
+static const struct snd_kcontrol_new int0_mi2s_rx_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new int4_mi2s_rx_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_HDMI_RX,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -4358,6 +4518,12 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -4451,6 +4617,12 @@ static const struct snd_kcontrol_new mmul2_mixer_controls[] = {
SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -4526,6 +4698,12 @@ static const struct snd_kcontrol_new mmul3_mixer_controls[] = {
SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ 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("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),
@@ -4604,6 +4782,12 @@ static const struct snd_kcontrol_new mmul4_mixer_controls[] = {
SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -4646,6 +4830,12 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = {
SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ 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("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),
@@ -4703,6 +4893,12 @@ static const struct snd_kcontrol_new mmul6_mixer_controls[] = {
SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -4760,6 +4956,12 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = {
SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -5113,6 +5315,42 @@ static const struct snd_kcontrol_new pri_mi2s_rx_voice_mixer_controls[] = {
msm_routing_put_voice_mixer),
};
+static const struct snd_kcontrol_new int0_mi2s_rx_voice_mixer_controls[] = {
+ SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+};
+
+static const struct snd_kcontrol_new int4_mi2s_rx_voice_mixer_controls[] = {
+ SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+};
+
static const struct snd_kcontrol_new tert_mi2s_rx_voice_mixer_controls[] = {
SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_TERTIARY_MI2S_RX,
MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
@@ -5777,6 +6015,9 @@ static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = {
SOC_SINGLE_EXT("TERT_MI2S_TX_MMode1",
MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1,
1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("INT3_MI2S_TX_MMode1",
+ MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1,
+ 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
SOC_SINGLE_EXT("SLIM_7_TX_MMode1",
MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1,
0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
@@ -5822,6 +6063,9 @@ static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = {
SOC_SINGLE_EXT("TERT_MI2S_TX_MMode2",
MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2,
1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("INT3_MI2S_TX_MMode2",
+ MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2,
+ 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
SOC_SINGLE_EXT("SLIM_7_TX_MMode2",
MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1,
0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
@@ -5867,6 +6111,9 @@ static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
SOC_SINGLE_EXT("TERT_MI2S_TX_Voip", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("INT3_MI2S_TX_Voip", MSM_BACKEND_DAI_INT3_MI2S_TX,
+ MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
SOC_SINGLE_EXT("SLIM_7_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_7_TX,
MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
@@ -5900,6 +6147,9 @@ static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = {
SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
+ SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX,
+ MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+ msm_routing_put_voice_stub_mixer),
SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
msm_routing_put_voice_stub_mixer),
@@ -6056,6 +6306,9 @@ static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = {
SOC_SINGLE_EXT("TERT_MI2S_TX_QCHAT", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("INT3_MI2S_TX_QCHAT", MSM_BACKEND_DAI_INT3_MI2S_TX,
+ MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
SOC_SINGLE_EXT("SLIM_7_TX_QCHAT", MSM_BACKEND_DAI_SLIMBUS_7_TX,
MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
@@ -7877,6 +8130,12 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
SND_SOC_DAPM_AIF_IN("HDMI_DL_HL", "HDMI_HOSTLESS Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("SEC_I2S_DL_HL", "SEC_I2S_RX_HOSTLESS Playback",
0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("INT0_MI2S_DL_HL",
+ "INT0 MI2S_RX Hostless Playback",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("INT4_MI2S_DL_HL",
+ "INT4 MI2S_RX Hostless Playback",
+ 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("PRI_MI2S_DL_HL",
"Primary MI2S_RX Hostless Playback",
0, 0, 0, 0),
@@ -8150,6 +8409,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("PRI_MI2S_RX", "Primary MI2S Playback",
0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("INT0_MI2S_RX", "INT0 MI2S Playback",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("INT4_MI2S_RX", "INT4 MI2S Playback",
+ 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_RX", "Quinary MI2S Playback",
0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0),
@@ -8160,6 +8423,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX", "Tertiary MI2S Capture",
0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("INT2_MI2S_TX", "INT2 MI2S Capture",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("INT3_MI2S_TX", "INT3 MI2S Capture",
+ 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX", "Secondary MI2S Capture",
0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0),
@@ -8444,6 +8711,12 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
SND_SOC_DAPM_MIXER("PRI_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
primary_mi2s_rx_mixer_controls,
ARRAY_SIZE(primary_mi2s_rx_mixer_controls)),
+ SND_SOC_DAPM_MIXER("INT0_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
+ int0_mi2s_rx_mixer_controls,
+ ARRAY_SIZE(int0_mi2s_rx_mixer_controls)),
+ SND_SOC_DAPM_MIXER("INT4_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
+ int4_mi2s_rx_mixer_controls,
+ ARRAY_SIZE(int4_mi2s_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("QUIN_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
quinary_mi2s_rx_mixer_controls,
ARRAY_SIZE(quinary_mi2s_rx_mixer_controls)),
@@ -8581,6 +8854,14 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
SND_SOC_NOPM, 0, 0,
pri_mi2s_rx_voice_mixer_controls,
ARRAY_SIZE(pri_mi2s_rx_voice_mixer_controls)),
+ SND_SOC_DAPM_MIXER("INT0_MI2S_RX_Voice Mixer",
+ SND_SOC_NOPM, 0, 0,
+ int0_mi2s_rx_voice_mixer_controls,
+ ARRAY_SIZE(int0_mi2s_rx_voice_mixer_controls)),
+ SND_SOC_DAPM_MIXER("INT4_MI2S_RX_Voice Mixer",
+ SND_SOC_NOPM, 0, 0,
+ int4_mi2s_rx_voice_mixer_controls,
+ ARRAY_SIZE(int4_mi2s_rx_voice_mixer_controls)),
SND_SOC_DAPM_MIXER("TERT_MI2S_RX_Voice Mixer",
SND_SOC_NOPM, 0, 0,
tert_mi2s_rx_voice_mixer_controls,
@@ -9082,6 +9363,42 @@ static const struct snd_soc_dapm_route intercon[] = {
{"PRI_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
{"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Audio Mixer"},
+ {"INT0_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"INT0_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"INT0_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"INT0_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"INT0_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"INT0_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"INT0_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"INT0_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"INT0_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"INT0_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"INT0_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"INT0_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"INT0_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"INT0_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"INT0_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX Audio Mixer"},
+
+ {"INT4_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"INT4_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"INT4_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"INT4_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"INT4_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"INT4_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"INT4_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"INT4_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"INT4_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"INT4_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"INT4_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"INT4_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"INT4_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"INT4_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"INT4_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX Audio Mixer"},
+
+ {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"QUIN_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"QUIN_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -9363,6 +9680,10 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia2 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"},
{"MultiMedia1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"MultiMedia2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"MultiMedia1 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"},
+ {"MultiMedia2 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"},
+ {"MultiMedia1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
+ {"MultiMedia2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
{"MultiMedia3 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"},
@@ -9384,6 +9705,12 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia6 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"MultiMedia3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"MultiMedia5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"MultiMedia6 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"},
+ {"MultiMedia3 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"},
+ {"MultiMedia5 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"},
+ {"MultiMedia6 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
+ {"MultiMedia3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
+ {"MultiMedia5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
{"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
@@ -9821,6 +10148,20 @@ static const struct snd_soc_dapm_route intercon[] = {
{"PRI_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"},
{"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_Voice Mixer"},
+ {"INT0_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"},
+ {"INT0_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"},
+ {"INT0_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
+ {"INT0_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"},
+ {"INT0_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"},
+ {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX_Voice Mixer"},
+
+ {"INT4_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"},
+ {"INT4_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"},
+ {"INT4_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"},
+ {"INT4_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"},
+ {"INT4_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"},
+ {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_Voice Mixer"},
+
{"TERT_MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
{"TERT_MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
{"TERT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"},
@@ -9992,6 +10333,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"VoiceMMode1_Tx Mixer", "PRI_MI2S_TX_MMode1", "PRI_MI2S_TX"},
{"VoiceMMode1_Tx Mixer", "MI2S_TX_MMode1", "MI2S_TX"},
{"VoiceMMode1_Tx Mixer", "TERT_MI2S_TX_MMode1", "TERT_MI2S_TX"},
+ {"VoiceMMode1_Tx Mixer", "INT3_MI2S_TX_MMode1", "INT3_MI2S_TX"},
{"VoiceMMode1_Tx Mixer", "SLIM_0_TX_MMode1", "SLIMBUS_0_TX"},
{"VoiceMMode1_Tx Mixer", "SLIM_7_TX_MMode1", "SLIMBUS_7_TX"},
{"VoiceMMode1_Tx Mixer", "SLIM_8_TX_MMode1", "SLIMBUS_8_TX"},
@@ -10008,6 +10350,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"VoiceMMode2_Tx Mixer", "PRI_MI2S_TX_MMode2", "PRI_MI2S_TX"},
{"VoiceMMode2_Tx Mixer", "MI2S_TX_MMode2", "MI2S_TX"},
{"VoiceMMode2_Tx Mixer", "TERT_MI2S_TX_MMode2", "TERT_MI2S_TX"},
+ {"VoiceMMode2_Tx Mixer", "INT3_MI2S_TX_MMode2", "INT3_MI2S_TX"},
{"VoiceMMode2_Tx Mixer", "SLIM_0_TX_MMode2", "SLIMBUS_0_TX"},
{"VoiceMMode2_Tx Mixer", "SLIM_7_TX_MMode2", "SLIMBUS_7_TX"},
{"VoiceMMode2_Tx Mixer", "SLIM_8_TX_MMode2", "SLIMBUS_8_TX"},
@@ -10023,6 +10366,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"},
{"Voip_Tx Mixer", "MI2S_TX_Voip", "MI2S_TX"},
{"Voip_Tx Mixer", "TERT_MI2S_TX_Voip", "TERT_MI2S_TX"},
+ {"Voip_Tx Mixer", "INT3_MI2S_TX_Voip", "INT3_MI2S_TX"},
{"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"},
{"Voip_Tx Mixer", "SLIM_7_TX_Voip", "SLIMBUS_7_TX"},
{"Voip_Tx Mixer", "SLIM_8_TX_Voip", "SLIMBUS_8_TX"},
@@ -10132,6 +10476,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"QCHAT_Tx Mixer", "MI2S_TX_QCHAT", "MI2S_TX"},
{"QCHAT_Tx Mixer", "PRI_MI2S_TX_QCHAT", "PRI_MI2S_TX"},
{"QCHAT_Tx Mixer", "TERT_MI2S_TX_QCHAT", "TERT_MI2S_TX"},
+ {"QCHAT_Tx Mixer", "INT3_MI2S_TX_QCHAT", "INT3_MI2S_TX"},
{"QCHAT_Tx Mixer", "USB_AUDIO_TX_QCHAT", "USB_AUDIO_TX"},
{"QCHAT_UL", NULL, "QCHAT_Tx Mixer"},
@@ -10149,6 +10494,10 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MI2S_UL_HL", NULL, "MI2S_TX"},
{"PCM_RX_DL_HL", "Switch", "SLIM0_DL_HL"},
{"PCM_RX", NULL, "PCM_RX_DL_HL"},
+ {"INT0_MI2S_RX_DL_HL", "Switch", "INT0_MI2S_DL_HL"},
+ {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX_DL_HL"},
+ {"INT4_MI2S_RX_DL_HL", "Switch", "INT4_MI2S_DL_HL"},
+ {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_DL_HL"},
{"PRI_MI2S_RX_DL_HL", "Switch", "PRI_MI2S_DL_HL"},
{"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_DL_HL"},
{"SEC_MI2S_RX_DL_HL", "Switch", "SEC_MI2S_DL_HL"},
@@ -10384,6 +10733,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"Voice Stub Tx Mixer", "MI2S_TX", "MI2S_TX"},
{"Voice Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"Voice Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"Voice Stub Tx Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"Voice Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
{"Voice Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"Voice Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"},
@@ -10561,6 +10911,8 @@ static const struct snd_soc_dapm_route intercon[] = {
{"BE_OUT", NULL, "SEC_MI2S_RX"},
{"BE_OUT", NULL, "SEC_MI2S_RX_SD1"},
{"BE_OUT", NULL, "PRI_MI2S_RX"},
+ {"BE_OUT", NULL, "INT0_MI2S_RX"},
+ {"BE_OUT", NULL, "INT4_MI2S_RX"},
{"BE_OUT", NULL, "INT_BT_SCO_RX"},
{"BE_OUT", NULL, "INT_BT_A2DP_RX"},
{"BE_OUT", NULL, "INT_FM_RX"},
@@ -10593,6 +10945,8 @@ static const struct snd_soc_dapm_route intercon[] = {
{"QUIN_MI2S_TX", NULL, "BE_IN"},
{"PRI_MI2S_TX", NULL, "BE_IN"},
{"TERT_MI2S_TX", NULL, "BE_IN"},
+ {"INT2_MI2S_TX", NULL, "BE_IN"},
+ {"INT3_MI2S_TX", NULL, "BE_IN"},
{"SEC_MI2S_TX", NULL, "BE_IN"},
{"SENARY_MI2S_TX", NULL, "BE_IN" },
{"SLIMBUS_0_TX", NULL, "BE_IN" },
@@ -10726,7 +11080,6 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
int i, path_type, session_type, topology;
struct msm_pcm_routing_bdai_data *bedai;
u32 channels, sample_rate;
- bool playback, capture;
uint16_t bits_per_sample = 16, voc_path_type;
struct msm_pcm_routing_fdai_data *fdai;
u32 session_id;
@@ -10762,8 +11115,6 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
* is started.
*/
bedai->active = 1;
- playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
- capture = substream->stream == SNDRV_PCM_STREAM_CAPTURE;
for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
fdai = &fe_dai_map[i][session_type];
@@ -10785,13 +11136,14 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
bits_per_sample = msm_routing_get_bit_width(
bedai->format);
- app_type = playback ?
- fe_dai_app_type_cfg[i].app_type : 0;
+ app_type =
+ fe_dai_app_type_cfg[i][session_type].app_type;
if (app_type) {
app_type_idx =
msm_pcm_routing_get_app_type_idx(app_type);
sample_rate =
- fe_dai_app_type_cfg[i].sample_rate;
+ fe_dai_app_type_cfg[i][session_type].
+ sample_rate;
bits_per_sample =
app_type_cfg[app_type_idx].bit_width;
} else
@@ -10804,8 +11156,10 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
channels = bedai->channel;
else
channels = bedai->adm_override_ch;
- acdb_dev_id = fe_dai_app_type_cfg[i].acdb_dev_id;
- topology = msm_routing_get_adm_topology(path_type, i);
+ acdb_dev_id =
+ fe_dai_app_type_cfg[i][session_type].acdb_dev_id;
+ topology = msm_routing_get_adm_topology(path_type, i,
+ session_type);
copp_idx = adm_open(bedai->port_id, path_type,
sample_rate, channels, topology,
fdai->perf_mode, bits_per_sample,
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index 8e3086849d92..8a62e900ff28 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -143,6 +143,21 @@
#define LPASS_BE_USB_AUDIO_RX "USB_AUDIO_RX"
#define LPASS_BE_USB_AUDIO_TX "USB_AUDIO_TX"
+
+#define LPASS_BE_INT0_MI2S_RX "INT0_MI2S_RX"
+#define LPASS_BE_INT0_MI2S_TX "INT0_MI2S_TX"
+#define LPASS_BE_INT1_MI2S_RX "INT1_MI2S_RX"
+#define LPASS_BE_INT1_MI2S_TX "INT1_MI2S_TX"
+#define LPASS_BE_INT2_MI2S_RX "INT2_MI2S_RX"
+#define LPASS_BE_INT2_MI2S_TX "INT2_MI2S_TX"
+#define LPASS_BE_INT3_MI2S_RX "INT3_MI2S_RX"
+#define LPASS_BE_INT3_MI2S_TX "INT3_MI2S_TX"
+#define LPASS_BE_INT4_MI2S_RX "INT4_MI2S_RX"
+#define LPASS_BE_INT4_MI2S_TX "INT4_MI2S_TX"
+#define LPASS_BE_INT5_MI2S_RX "INT5_MI2S_RX"
+#define LPASS_BE_INT5_MI2S_TX "INT5_MI2S_TX"
+#define LPASS_BE_INT6_MI2S_RX "INT6_MI2S_RX"
+#define LPASS_BE_INT6_MI2S_TX "INT6_MI2S_TX"
/* For multimedia front-ends, asm session is allocated dynamically.
* Hence, asm session/multimedia front-end mapping has to be maintained.
* Due to this reason, additional multimedia front-end must be placed before
@@ -321,6 +336,20 @@ enum {
MSM_BACKEND_DAI_TERT_AUXPCM_TX,
MSM_BACKEND_DAI_QUAT_AUXPCM_RX,
MSM_BACKEND_DAI_QUAT_AUXPCM_TX,
+ MSM_BACKEND_DAI_INT0_MI2S_RX,
+ MSM_BACKEND_DAI_INT0_MI2S_TX,
+ MSM_BACKEND_DAI_INT1_MI2S_RX,
+ MSM_BACKEND_DAI_INT1_MI2S_TX,
+ MSM_BACKEND_DAI_INT2_MI2S_RX,
+ MSM_BACKEND_DAI_INT2_MI2S_TX,
+ MSM_BACKEND_DAI_INT3_MI2S_RX,
+ MSM_BACKEND_DAI_INT3_MI2S_TX,
+ MSM_BACKEND_DAI_INT4_MI2S_RX,
+ MSM_BACKEND_DAI_INT4_MI2S_TX,
+ MSM_BACKEND_DAI_INT5_MI2S_RX,
+ MSM_BACKEND_DAI_INT5_MI2S_TX,
+ MSM_BACKEND_DAI_INT6_MI2S_RX,
+ MSM_BACKEND_DAI_INT6_MI2S_TX,
MSM_BACKEND_DAI_MAX,
};
@@ -432,7 +461,7 @@ void msm_pcm_routing_acquire_lock(void);
void msm_pcm_routing_release_lock(void);
void msm_pcm_routing_reg_stream_app_type_cfg(int fedai_id, int app_type,
- int acdb_dev_id, int sample_rate);
-int msm_pcm_routing_get_stream_app_type_cfg(int fedai_id, int *app_type,
- int *acdb_dev_id, int *sample_rate);
+ int acdb_dev_id, int sample_rate, int session_type);
+int msm_pcm_routing_get_stream_app_type_cfg(int fedai_id, int session_type,
+ int *app_type, int *acdb_dev_id, int *sample_rate);
#endif /*_MSM_PCM_H*/
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index 78546fef7b3b..c75f7214db1a 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -483,6 +483,13 @@ int afe_get_port_type(u16 port_id)
case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
case AFE_PORT_ID_USB_RX:
+ case AFE_PORT_ID_INT0_MI2S_RX:
+ case AFE_PORT_ID_INT1_MI2S_RX:
+ case AFE_PORT_ID_INT2_MI2S_RX:
+ case AFE_PORT_ID_INT3_MI2S_RX:
+ case AFE_PORT_ID_INT4_MI2S_RX:
+ case AFE_PORT_ID_INT5_MI2S_RX:
+ case AFE_PORT_ID_INT6_MI2S_RX:
ret = MSM_AFE_PORT_TYPE_RX;
break;
@@ -547,6 +554,13 @@ int afe_get_port_type(u16 port_id)
case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
case AFE_PORT_ID_USB_TX:
+ case AFE_PORT_ID_INT0_MI2S_TX:
+ case AFE_PORT_ID_INT1_MI2S_TX:
+ case AFE_PORT_ID_INT2_MI2S_TX:
+ case AFE_PORT_ID_INT3_MI2S_TX:
+ case AFE_PORT_ID_INT4_MI2S_TX:
+ case AFE_PORT_ID_INT5_MI2S_TX:
+ case AFE_PORT_ID_INT6_MI2S_TX:
ret = MSM_AFE_PORT_TYPE_TX;
break;
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 2874a334dfdd..22e14f431bb3 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -3015,7 +3015,8 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac,
int dir)
{
struct audio_buffer *buf_circ;
- int bytes_to_alloc, rc, len;
+ int bytes_to_alloc, rc;
+ size_t len;
buf_circ = kzalloc(sizeof(struct audio_buffer), GFP_KERNEL);
@@ -3034,7 +3035,7 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac,
rc = msm_audio_ion_alloc("audio_client", &buf_circ->client,
&buf_circ->handle, bytes_to_alloc,
(ion_phys_addr_t *)&buf_circ->phys,
- (size_t *)&len, &buf_circ->data);
+ &len, &buf_circ->data);
if (rc) {
pr_err("%s: Audio ION alloc is failed, rc = %d\n", __func__,
@@ -3076,7 +3077,8 @@ int q6asm_set_shared_pos_buff(struct audio_client *ac,
int dir)
{
struct audio_buffer *buf_pos = &ac->shared_pos_buf;
- int len, rc;
+ int rc;
+ size_t len;
int bytes_to_alloc = sizeof(struct asm_shared_position_buffer);
mutex_lock(&ac->cmd_lock);
@@ -3085,7 +3087,7 @@ int q6asm_set_shared_pos_buff(struct audio_client *ac,
rc = msm_audio_ion_alloc("audio_client", &buf_pos->client,
&buf_pos->handle, bytes_to_alloc,
- (ion_phys_addr_t *)&buf_pos->phys, (size_t *)&len,
+ (ion_phys_addr_t *)&buf_pos->phys, &len,
&buf_pos->data);
if (rc) {
@@ -5848,7 +5850,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
struct asm_buffer_node *buffer_node = NULL;
int rc = 0;
int i = 0;
- int cmd_size = 0;
+ uint32_t cmd_size = 0;
uint32_t bufcnt_t;
uint32_t bufsz_t;
@@ -5870,10 +5872,25 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
bufsz_t = PAGE_ALIGN(bufsz_t);
}
+ if (bufcnt_t > (UINT_MAX
+ - sizeof(struct avs_cmd_shared_mem_map_regions))
+ / sizeof(struct avs_shared_map_region_payload)) {
+ pr_err("%s: Unsigned Integer Overflow. bufcnt_t = %u\n",
+ __func__, bufcnt_t);
+ return -EINVAL;
+ }
+
cmd_size = sizeof(struct avs_cmd_shared_mem_map_regions)
+ (sizeof(struct avs_shared_map_region_payload)
* bufcnt_t);
+
+ if (bufcnt > (UINT_MAX / sizeof(struct asm_buffer_node))) {
+ pr_err("%s: Unsigned Integer Overflow. bufcnt = %u\n",
+ __func__, bufcnt);
+ return -EINVAL;
+ }
+
buffer_node = kzalloc(sizeof(struct asm_buffer_node) * bufcnt,
GFP_KERNEL);
if (!buffer_node) {
diff --git a/sound/soc/msm/qdsp6v2/q6audio-v2.c b/sound/soc/msm/qdsp6v2/q6audio-v2.c
index 99f5f0e1a5a5..84e1178dc354 100644
--- a/sound/soc/msm/qdsp6v2/q6audio-v2.c
+++ b/sound/soc/msm/qdsp6v2/q6audio-v2.c
@@ -233,6 +233,34 @@ int q6audio_get_port_index(u16 port_id)
return IDX_AFE_PORT_ID_USB_RX;
case AFE_PORT_ID_USB_TX:
return IDX_AFE_PORT_ID_USB_TX;
+ case AFE_PORT_ID_INT0_MI2S_RX:
+ return IDX_AFE_PORT_ID_INT0_MI2S_RX;
+ case AFE_PORT_ID_INT0_MI2S_TX:
+ return IDX_AFE_PORT_ID_INT0_MI2S_TX;
+ case AFE_PORT_ID_INT1_MI2S_RX:
+ return IDX_AFE_PORT_ID_INT1_MI2S_RX;
+ case AFE_PORT_ID_INT1_MI2S_TX:
+ return IDX_AFE_PORT_ID_INT1_MI2S_TX;
+ case AFE_PORT_ID_INT2_MI2S_RX:
+ return IDX_AFE_PORT_ID_INT2_MI2S_RX;
+ case AFE_PORT_ID_INT2_MI2S_TX:
+ return IDX_AFE_PORT_ID_INT2_MI2S_TX;
+ case AFE_PORT_ID_INT3_MI2S_RX:
+ return IDX_AFE_PORT_ID_INT3_MI2S_RX;
+ case AFE_PORT_ID_INT3_MI2S_TX:
+ return IDX_AFE_PORT_ID_INT3_MI2S_TX;
+ case AFE_PORT_ID_INT4_MI2S_RX:
+ return IDX_AFE_PORT_ID_INT4_MI2S_RX;
+ case AFE_PORT_ID_INT4_MI2S_TX:
+ return IDX_AFE_PORT_ID_INT4_MI2S_TX;
+ case AFE_PORT_ID_INT5_MI2S_RX:
+ return IDX_AFE_PORT_ID_INT5_MI2S_RX;
+ case AFE_PORT_ID_INT5_MI2S_TX:
+ return IDX_AFE_PORT_ID_INT5_MI2S_TX;
+ case AFE_PORT_ID_INT6_MI2S_RX:
+ return IDX_AFE_PORT_ID_INT6_MI2S_RX;
+ case AFE_PORT_ID_INT6_MI2S_TX:
+ return IDX_AFE_PORT_ID_INT6_MI2S_TX;
default: return -EINVAL;
}
}
@@ -452,6 +480,34 @@ int q6audio_get_port_id(u16 port_id)
return AFE_PORT_ID_USB_RX;
case AFE_PORT_ID_USB_TX:
return AFE_PORT_ID_USB_TX;
+ case AFE_PORT_ID_INT0_MI2S_RX:
+ return AFE_PORT_ID_INT0_MI2S_RX;
+ case AFE_PORT_ID_INT0_MI2S_TX:
+ return AFE_PORT_ID_INT0_MI2S_TX;
+ case AFE_PORT_ID_INT1_MI2S_RX:
+ return AFE_PORT_ID_INT1_MI2S_RX;
+ case AFE_PORT_ID_INT1_MI2S_TX:
+ return AFE_PORT_ID_INT1_MI2S_TX;
+ case AFE_PORT_ID_INT2_MI2S_RX:
+ return AFE_PORT_ID_INT2_MI2S_RX;
+ case AFE_PORT_ID_INT2_MI2S_TX:
+ return AFE_PORT_ID_INT2_MI2S_TX;
+ case AFE_PORT_ID_INT3_MI2S_RX:
+ return AFE_PORT_ID_INT3_MI2S_RX;
+ case AFE_PORT_ID_INT3_MI2S_TX:
+ return AFE_PORT_ID_INT3_MI2S_TX;
+ case AFE_PORT_ID_INT4_MI2S_RX:
+ return AFE_PORT_ID_INT4_MI2S_RX;
+ case AFE_PORT_ID_INT4_MI2S_TX:
+ return AFE_PORT_ID_INT4_MI2S_TX;
+ case AFE_PORT_ID_INT5_MI2S_RX:
+ return AFE_PORT_ID_INT5_MI2S_RX;
+ case AFE_PORT_ID_INT5_MI2S_TX:
+ return AFE_PORT_ID_INT5_MI2S_TX;
+ case AFE_PORT_ID_INT6_MI2S_RX:
+ return AFE_PORT_ID_INT6_MI2S_RX;
+ case AFE_PORT_ID_INT6_MI2S_TX:
+ return AFE_PORT_ID_INT6_MI2S_TX;
default:
pr_warn("%s: Invalid port_id %d\n", __func__, port_id);
return -EINVAL;
@@ -572,6 +628,20 @@ int q6audio_is_digital_pcm_interface(u16 port_id)
case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
case AFE_PORT_ID_SENARY_MI2S_TX:
+ case AFE_PORT_ID_INT0_MI2S_RX:
+ case AFE_PORT_ID_INT0_MI2S_TX:
+ case AFE_PORT_ID_INT1_MI2S_RX:
+ case AFE_PORT_ID_INT1_MI2S_TX:
+ case AFE_PORT_ID_INT2_MI2S_RX:
+ case AFE_PORT_ID_INT2_MI2S_TX:
+ case AFE_PORT_ID_INT3_MI2S_RX:
+ case AFE_PORT_ID_INT3_MI2S_TX:
+ case AFE_PORT_ID_INT4_MI2S_RX:
+ case AFE_PORT_ID_INT4_MI2S_TX:
+ case AFE_PORT_ID_INT5_MI2S_RX:
+ case AFE_PORT_ID_INT5_MI2S_TX:
+ case AFE_PORT_ID_INT6_MI2S_RX:
+ case AFE_PORT_ID_INT6_MI2S_TX:
break;
default:
ret = -EINVAL;
@@ -710,6 +780,20 @@ int q6audio_validate_port(u16 port_id)
case AFE_PORT_ID_SENARY_MI2S_TX:
case AFE_PORT_ID_USB_RX:
case AFE_PORT_ID_USB_TX:
+ case AFE_PORT_ID_INT0_MI2S_RX:
+ case AFE_PORT_ID_INT0_MI2S_TX:
+ case AFE_PORT_ID_INT1_MI2S_RX:
+ case AFE_PORT_ID_INT1_MI2S_TX:
+ case AFE_PORT_ID_INT2_MI2S_RX:
+ case AFE_PORT_ID_INT2_MI2S_TX:
+ case AFE_PORT_ID_INT3_MI2S_RX:
+ case AFE_PORT_ID_INT3_MI2S_TX:
+ case AFE_PORT_ID_INT4_MI2S_RX:
+ case AFE_PORT_ID_INT4_MI2S_TX:
+ case AFE_PORT_ID_INT5_MI2S_RX:
+ case AFE_PORT_ID_INT5_MI2S_TX:
+ case AFE_PORT_ID_INT6_MI2S_RX:
+ case AFE_PORT_ID_INT6_MI2S_TX:
{
ret = 0;
break;
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index 3b3e728f88f2..834fe7c05306 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -142,7 +142,7 @@ struct share_mem_buf {
struct mem_map_table {
dma_addr_t phys;
void *data;
- uint32_t size; /* size of buffer */
+ size_t size; /* size of buffer */
struct ion_handle *handle;
struct ion_client *client;
};
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index c8f45b4efa21..eb894d073c07 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -68,7 +68,8 @@ out:
static int soc_compr_open_fe(struct snd_compr_stream *cstream)
{
struct snd_soc_pcm_runtime *fe = cstream->private_data;
- struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
+ struct snd_pcm_substream *fe_substream =
+ fe->pcm->streams[cstream->direction].substream;
struct snd_soc_platform *platform = fe->platform;
struct snd_soc_dpcm *dpcm;
struct snd_soc_dapm_widget_list *list;
@@ -443,7 +444,8 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
struct snd_compr_params *params)
{
struct snd_soc_pcm_runtime *fe = cstream->private_data;
- struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
+ struct snd_pcm_substream *fe_substream =
+ fe->pcm->streams[cstream->direction].substream;
struct snd_soc_platform *platform = fe->platform;
struct snd_soc_pcm_runtime *be_list[DPCM_MAX_BE_USERS];
struct snd_soc_dpcm *dpcm;
@@ -852,8 +854,8 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
}
}
- printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name,
- cpu_dai->name);
+ dev_dbg(rtd->card->dev, "compress asoc: %s <-> %s mapping ok\n",
+ codec_dai->name, cpu_dai->name);
return ret;
compr_err:
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 4ef20ba02cb4..13649f96b370 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -3017,7 +3017,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
pcm->private_free = platform->driver->pcm_free;
out:
- dev_info(rtd->card->dev, "%s <-> %s mapping ok\n",
+ dev_dbg(rtd->card->dev, "%s <-> %s mapping ok\n",
(rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name,
cpu_dai->name);
return ret;