Compare commits
197 commits
master
...
stable/5.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e7ada8afb | ||
|
|
48eb7f83fd | ||
|
|
abf97bcc76 | ||
|
|
942aaa154c | ||
|
|
602ab167d2 | ||
|
|
91b9ae6727 | ||
|
|
4f91b8177d | ||
|
|
850e278092 | ||
|
|
2be5847b59 | ||
|
|
c1d25d8c05 | ||
|
|
1d85017e93 | ||
|
|
efdaf94d40 | ||
|
|
9751baa34a | ||
|
|
7201704f36 | ||
|
|
91a7301ff7 | ||
|
|
597fdc391d | ||
|
|
b27451eb8e | ||
|
|
42c07833ee | ||
|
|
22b86a2ead | ||
|
|
6e6983a54b | ||
|
|
d57d5446bd | ||
|
|
2f12750a9f | ||
|
|
5e521b61d3 | ||
|
|
f70ce939cc | ||
|
|
fec317a4ed | ||
|
|
7a70912605 | ||
|
|
7773a752b2 | ||
|
|
4940fa49b4 | ||
|
|
79cdaeec85 | ||
|
|
ad19565871 | ||
|
|
57138d33c6 | ||
|
|
3cb4d243a9 | ||
|
|
18ffadb11d | ||
|
|
f41a398851 | ||
|
|
66b7f663b9 | ||
|
|
768863d390 | ||
|
|
4115eb289f | ||
|
|
48583bd772 | ||
|
|
6ca315eeb2 | ||
|
|
32c9efff0c | ||
|
|
f841fd5fca | ||
|
|
6349f882a9 | ||
|
|
74f295b703 | ||
|
|
7bb9ae5690 | ||
|
|
227809af23 | ||
|
|
d2bc8eead8 | ||
|
|
772df79320 | ||
|
|
08f49b4e01 | ||
|
|
5acf9144e4 | ||
|
|
fe4f19206b | ||
|
|
d9bd889d00 | ||
|
|
24c173eb1a | ||
|
|
6c078183c7 | ||
|
|
5f8c475110 | ||
|
|
2e983e626a | ||
|
|
4574a11b86 | ||
|
|
bd990ac32a | ||
|
|
cf3f0de277 | ||
|
|
cc0b5035c1 | ||
|
|
2f5081d23c | ||
|
|
adc007cc00 | ||
|
|
b04964f4c1 | ||
|
|
85d4bbdf85 | ||
|
|
a96260e915 | ||
|
|
df055f7b7f | ||
|
|
d954b16251 | ||
|
|
48f050eb4d | ||
|
|
eb0411a669 | ||
|
|
86dea5456c | ||
|
|
1b758aceea | ||
|
|
fde6bbe1ee | ||
|
|
9083a32532 | ||
|
|
a18a9850aa | ||
|
|
a1e7e1e597 | ||
|
|
8e7ca27eb9 | ||
|
|
924d6db5ae | ||
|
|
148c6bb847 | ||
|
|
2c34128296 | ||
|
|
2b9eb2cf36 | ||
|
|
de04ce2411 | ||
|
|
7c39a9b602 | ||
|
|
60f92b391e | ||
|
|
820a7ce001 | ||
|
|
d4e258c908 | ||
|
|
607c599b1d | ||
|
|
5890456b65 | ||
|
|
5ec5a8cb65 | ||
|
|
94bfcbdfd4 | ||
|
|
de2513ec19 | ||
|
|
a47080849e | ||
|
|
f5cfd7f95b | ||
|
|
1d4c0f12fd | ||
|
|
8084acbe66 | ||
|
|
d5b281a2f6 | ||
|
|
891b2ae7c2 | ||
|
|
0a3289cee8 | ||
|
|
0be74b7ad7 | ||
|
|
cbf3502c0b | ||
|
|
cc9681773f | ||
|
|
9c7ac5c1b8 | ||
|
|
dc9624ed78 | ||
|
|
9bc4d550c8 | ||
|
|
39b5b6a96d | ||
|
|
8717e14bea | ||
|
|
0754da18bc | ||
|
|
442a308c69 | ||
|
|
a271945e7f | ||
|
|
814a6f0160 | ||
|
|
3002121529 | ||
|
|
ad3f6572c0 | ||
|
|
24a7f77342 | ||
|
|
af19ac27f5 | ||
|
|
a09afd49a4 | ||
|
|
f755977ef2 | ||
|
|
5bec3e2f17 | ||
|
|
be61734774 | ||
|
|
aff1b0223e | ||
|
|
26ce8fecfd | ||
|
|
8a2ccff55c | ||
|
|
861f7e7acd | ||
|
|
5447eb29ff | ||
|
|
6ff7a9cb30 | ||
|
|
183c8b6a9a | ||
|
|
35135e4914 | ||
|
|
69f590f3da | ||
|
|
f6c39af1ea | ||
|
|
9e183f76e5 | ||
|
|
ed5883aaf6 | ||
|
|
080ec6bbe7 | ||
|
|
18e8017b29 | ||
|
|
c885887990 | ||
|
|
332384ce61 | ||
|
|
208b018dba | ||
|
|
e17fc9fe80 | ||
|
|
a308847c12 | ||
|
|
55f5a6170d | ||
|
|
a76fe9c162 | ||
|
|
c3a5e2c6fe | ||
|
|
3d37e781a0 | ||
|
|
7ea1c46ab6 | ||
|
|
9645ae9cf0 | ||
|
|
94742372b9 | ||
|
|
0af29df528 | ||
|
|
67c90625b8 | ||
|
|
89a28710d9 | ||
|
|
39f59fc175 | ||
|
|
9c0486fff7 | ||
|
|
55afacfffc | ||
|
|
cbd0009163 | ||
|
|
0047d57e6c | ||
|
|
8021340589 | ||
|
|
453f815665 | ||
|
|
068108f538 | ||
|
|
08467db994 | ||
|
|
fdb1b354e3 | ||
|
|
09ea8bc727 | ||
|
|
806afdc6d9 | ||
|
|
463ebd6f87 | ||
|
|
4f276d40e6 | ||
|
|
6fd3ff02da | ||
|
|
da71481fef | ||
|
|
4df97cbda2 | ||
|
|
05daffcd83 | ||
|
|
91657c81fc | ||
|
|
d9394ac04e | ||
|
|
68f784cbb1 | ||
|
|
443a7b15c8 | ||
|
|
4d77c5dc80 | ||
|
|
e84123f904 | ||
|
|
a199b1cf0d | ||
|
|
65419736ad | ||
|
|
3cac6963de | ||
|
|
1e34e244a3 | ||
|
|
157edd57d5 | ||
|
|
0e4944c9c1 | ||
|
|
7176e96d79 | ||
|
|
f0cb039571 | ||
|
|
8f4d6e33b5 | ||
|
|
7ebcfba533 | ||
|
|
32a177ccb3 | ||
|
|
d161ede79b | ||
|
|
c379810324 | ||
|
|
cca2a7ad06 | ||
|
|
a9ebafbe00 | ||
|
|
9d3ee85be1 | ||
|
|
f4e9fe58d4 | ||
|
|
955a870ebd | ||
|
|
7a5a2e2ccf | ||
|
|
62d1c104c7 | ||
|
|
d0d24c89d8 | ||
|
|
9a51867dc5 | ||
|
|
f11c51290d | ||
|
|
9d923d15fc | ||
|
|
a27dffcb93 | ||
|
|
3162bd8ac0 | ||
|
|
8c37b3bc82 | ||
|
|
eca56bf006 |
158 changed files with 21533 additions and 2025 deletions
|
|
@ -994,6 +994,9 @@ This is a directory, with the following entries:
|
|||
* ``boot_id``: a UUID generated the first time this is retrieved, and
|
||||
unvarying after that;
|
||||
|
||||
* ``uuid``: a UUID generated every time this is retrieved (this can
|
||||
thus be used to generate UUIDs at will);
|
||||
|
||||
* ``entropy_avail``: the pool's entropy count, in bits;
|
||||
|
||||
* ``poolsize``: the entropy pool size, in bits;
|
||||
|
|
@ -1001,10 +1004,7 @@ This is a directory, with the following entries:
|
|||
* ``urandom_min_reseed_secs``: obsolete (used to determine the minimum
|
||||
number of seconds between urandom pool reseeding). This file is
|
||||
writable for compatibility purposes, but writing to it has no effect
|
||||
on any RNG behavior.
|
||||
|
||||
* ``uuid``: a UUID generated every time this is retrieved (this can
|
||||
thus be used to generate UUIDs at will);
|
||||
on any RNG behavior;
|
||||
|
||||
* ``write_wakeup_threshold``: when the entropy count drops below this
|
||||
(as a number of bits), processes waiting to write to ``/dev/random``
|
||||
|
|
|
|||
|
|
@ -316,6 +316,12 @@ properties:
|
|||
|
||||
* arm/msm/qcom,kpss-acc.txt
|
||||
|
||||
qcom,freq-domain:
|
||||
$ref: '/schemas/types.yaml#/definitions/phandle-array'
|
||||
description: |
|
||||
CPUs supporting freq-domain must set their "qcom,freq-domain" property
|
||||
with phandle to a cpufreq_hw node followed by the Domain ID(0/1).
|
||||
|
||||
rockchip,pmu:
|
||||
$ref: '/schemas/types.yaml#/definitions/phandle'
|
||||
description: |
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ description: |
|
|||
sa8155p
|
||||
sc7180
|
||||
sc7280
|
||||
msm8998
|
||||
sdm630
|
||||
sdm632
|
||||
sdm660
|
||||
|
|
@ -225,6 +226,20 @@ properties:
|
|||
- google,senor
|
||||
- const: qcom,sc7280
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- asus,novago-tp370ql
|
||||
- fxtec,pro1
|
||||
- hp,envy-x2
|
||||
- lenovo,miix-630
|
||||
- oneplus,cheeseburger
|
||||
- oneplus,dumpling
|
||||
- qcom,msm8998-mtp
|
||||
- sony,xperia-lilac
|
||||
- sony,xperia-maple
|
||||
- sony,xperia-poplar
|
||||
- const: qcom,msm8998
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- fairphone,fp3
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ description: |
|
|||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- description: Non-secure v1 of CPUFREQ HW
|
||||
items:
|
||||
- const: qcom,cpufreq-hw-8998
|
||||
|
||||
- description: v1 of CPUFREQ HW
|
||||
items:
|
||||
- const: qcom,cpufreq-hw
|
||||
|
|
@ -28,19 +32,9 @@ properties:
|
|||
- qcom,sm8250-cpufreq-epss
|
||||
- const: qcom,cpufreq-epss
|
||||
|
||||
reg:
|
||||
minItems: 2
|
||||
items:
|
||||
- description: Frequency domain 0 register region
|
||||
- description: Frequency domain 1 register region
|
||||
- description: Frequency domain 2 register region
|
||||
reg: {}
|
||||
|
||||
reg-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: freq-domain0
|
||||
- const: freq-domain1
|
||||
- const: freq-domain2
|
||||
reg-names: {}
|
||||
|
||||
clocks:
|
||||
items:
|
||||
|
|
@ -55,9 +49,52 @@ properties:
|
|||
'#freq-domain-cells':
|
||||
const: 1
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: qcom,cpufreq-hw-8998
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
minItems: 2
|
||||
items:
|
||||
- description: Frequency domain 0 register region
|
||||
- description: Operating State Manager domain 0 register region
|
||||
- description: Frequency domain 1 register region
|
||||
- description: Operating State Manager domain 1 register region
|
||||
- description: PLL ACD domain 0 register region (if ACD programming required)
|
||||
- description: PLL ACD domain 1 register region (if ACD programming required)
|
||||
|
||||
reg-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: "osm-domain0"
|
||||
- const: "freq-domain0"
|
||||
- const: "osm-domain1"
|
||||
- const: "freq-domain1"
|
||||
- const: "osm-acd0"
|
||||
- const: "osm-acd1"
|
||||
|
||||
else:
|
||||
properties:
|
||||
reg:
|
||||
minItems: 2
|
||||
items:
|
||||
- description: Frequency domain 0 register region
|
||||
- description: Frequency domain 1 register region
|
||||
- description: Frequency domain 2 register region
|
||||
reg-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: "freq-domain0"
|
||||
- const: "freq-domain1"
|
||||
- const: "freq-domain2"
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#freq-domain-cells'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/samsung,s6e3fa5.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung S6E3FA5 AMOLED panel with command mode DSI controller
|
||||
|
||||
maintainers:
|
||||
- Jami Kettunen <jami.kettunen@somainline.org>
|
||||
|
||||
description: |+
|
||||
This panel is found on the OnePlus 3T as well as OnePlus 5,
|
||||
however on the 3T it runs in video mode while this driver
|
||||
currently only support the command mode variant found on the
|
||||
5.
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: samsung,s6e3fa5
|
||||
reg: true
|
||||
reset-gpios: true
|
||||
disp-te-gpios: true
|
||||
vddio-supply:
|
||||
description: vddio supply
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vddio-supply
|
||||
- reset-gpios
|
||||
- disp-te-gpios
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
panel@0 {
|
||||
reg = <0>;
|
||||
|
||||
compatible = "samsung,s6e3fa5";
|
||||
|
||||
vddio-supply = <&vreg_l14a_1p88>;
|
||||
reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
|
||||
disp-te-gpios = <&tlmm 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/samsung,s6e3fc1.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung S6E3FC1 AMOLED panel with command mode DSI controller
|
||||
|
||||
maintainers:
|
||||
- Jami Kettunen <jami.kettunen@somainline.org>
|
||||
|
||||
description: |+
|
||||
This panel is found on the OnePlus 5T and it runs in command mode.
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: samsung,s6e3fc1
|
||||
reg: true
|
||||
reset-gpios: true
|
||||
disp-te-gpios: true
|
||||
vddio-supply:
|
||||
description: vddio supply
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vddio-supply
|
||||
- reset-gpios
|
||||
- disp-te-gpios
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
panel@0 {
|
||||
reg = <0>;
|
||||
|
||||
compatible = "samsung,s6e3fc1";
|
||||
|
||||
vddio-supply = <&vreg_l14a_1p88>;
|
||||
reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
|
||||
disp-te-gpios = <&tlmm 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
Qualcomm Universal Peripheral (QUP) I2C controller
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be:
|
||||
* "qcom,i2c-qup-v1.1.1" for 8660, 8960 and 8064.
|
||||
* "qcom,i2c-qup-v2.1.1" for 8974 v1.
|
||||
* "qcom,i2c-qup-v2.2.1" for 8974 v2 and later.
|
||||
- reg: Should contain QUP register address and length.
|
||||
- interrupts: Should contain I2C interrupt.
|
||||
|
||||
- clocks: A list of phandles + clock-specifiers, one for each entry in
|
||||
clock-names.
|
||||
- clock-names: Should contain:
|
||||
* "core" for the core clock
|
||||
* "iface" for the AHB clock
|
||||
|
||||
- #address-cells: Should be <1> Address cells for i2c device address
|
||||
- #size-cells: Should be <0> as i2c addresses have no size component
|
||||
|
||||
Optional properties:
|
||||
- clock-frequency: Should specify the desired i2c bus clock frequency in Hz,
|
||||
defaults to 100kHz if omitted.
|
||||
|
||||
Child nodes should conform to i2c bus binding.
|
||||
|
||||
Example:
|
||||
|
||||
i2c@f9924000 {
|
||||
compatible = "qcom,i2c-qup-v2.2.1";
|
||||
reg = <0xf9924000 0x1000>;
|
||||
interrupts = <0 96 0>;
|
||||
|
||||
clocks = <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
|
||||
clock-names = "core", "iface";
|
||||
|
||||
clock-frequency = <355000>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
101
Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml
Normal file
101
Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
|
||||
$id: http://devicetree.org/schemas/i2c/qcom,i2c-qup.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Universal Peripheral (QUP) I2C controller
|
||||
|
||||
maintainers:
|
||||
- Andy Gross <agross@kernel.org>
|
||||
- Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||
|
||||
description: Binding for Qualcomm "QUP" I2C controllers
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/i2c/i2c-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,i2c-qup-v1.1.1
|
||||
- qcom,i2c-qup-v2.1.1
|
||||
- qcom,i2c-qup-v2.2.1
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: QUP I2C register iospace
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Core QUP I2C clock
|
||||
- description: AHB clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: core
|
||||
- const: iface
|
||||
|
||||
clock-frequency:
|
||||
minimum: 100000
|
||||
maximum: 1000000
|
||||
default: 100000
|
||||
|
||||
dmas:
|
||||
items:
|
||||
- description: RX DMA Channel phandle
|
||||
- description: TX DMA Channel phandle
|
||||
|
||||
dma-names:
|
||||
items:
|
||||
- const: rx
|
||||
- const: tx
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
qcom,noise-reject-sda:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Noise rejection level for the SDA line.
|
||||
minimum: 0
|
||||
maximum: 3
|
||||
default: 0
|
||||
|
||||
qcom,noise-reject-scl:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Noise rejection level for the SCL line.
|
||||
minimum: 0
|
||||
maximum: 3
|
||||
default: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-msm8998.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
i2c@c175000 {
|
||||
compatible = "qcom,i2c-qup-v2.2.1";
|
||||
reg = <0x0c175000 0x600>;
|
||||
interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&gcc GCC_BLSP1_QUP1_I2C_APPS_CLK>,
|
||||
<&gcc GCC_BLSP1_AHB_CLK>;
|
||||
clock-names = "core", "iface";
|
||||
clock-frequency = <400000>;
|
||||
dmas = <&blsp_dma 4>, <&blsp_dma 5>;
|
||||
dma-names = "rx", "tx";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/adc/qcom,spmi-rradc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm's SPMI PMIC Round Robin ADC
|
||||
|
||||
maintainers:
|
||||
- Caleb Connolly <caleb.connolly@linaro.org>
|
||||
|
||||
description: |
|
||||
The Qualcomm SPMI Round Robin ADC (RRADC) provides interface to clients to
|
||||
read the voltage, current and temperature for supported peripherals such as
|
||||
the battery thermistor die temperature, charger temperature, USB and DC input
|
||||
voltage / current and battery ID resistor.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,pmi8998-rradc
|
||||
- qcom,pm660-rradc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
qcom,batt-id-delay-ms:
|
||||
description: Sets the hardware settling time for the battery ID resistor.
|
||||
enum: [0, 1, 4, 12, 20, 40, 60, 80]
|
||||
|
||||
"#io-channel-cells":
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
pmic {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pmic_rradc: adc@4500 {
|
||||
compatible = "qcom,pmi8998-rradc";
|
||||
reg = <0x4500>;
|
||||
#io-channel-cells = <1>;
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/input/gpio-fastmatrix-keyboard.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Fast modern GPIO-driven keyboard/keypad matrix driver binding
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
|
||||
|
||||
description: |
|
||||
A simple common binding for matrix-connected keyboards/keypads, targeted at
|
||||
defining the keys in the scope of linux key codes since that is a stable and
|
||||
standardized interface at this time.
|
||||
This driver uses the GPIOD API in order to support setting (and reading) an
|
||||
entire array of GPIOs which is very fast (if the controller supports it) and
|
||||
a requirement to support full keyboard matrices on slow external GPIO I2C
|
||||
expanders, but also a great latency enhancement for faster GPIO controllers.
|
||||
|
||||
allOf:
|
||||
- $ref: input.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: gpio-fastmatrix-keyboard
|
||||
|
||||
label:
|
||||
description: Descriptive name of the key.
|
||||
|
||||
linux,keymap:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description: |
|
||||
An array of packed 1-cell entries containing the equivalent of row,
|
||||
column and linux key-code as specified in dt-bindings/input/input.h
|
||||
|
||||
autorescan-ms:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
Activates auto-rescanning of the matrix after receiving and processing
|
||||
an event for quirky hardware that won't re-send interrupts on fast-press,
|
||||
fast-depress, or multiple keys pressed events.
|
||||
This time is expressed in milliseconds; if not specified, the feature is
|
||||
disabled.
|
||||
|
||||
col-scan-delay-us:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
Time to wait in microseconds for scan after activating a column.
|
||||
If not specified, the default is 0 (no wait).
|
||||
|
||||
debounce-delay-ms:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
Matrix button debouncing interval time in milliseconds.
|
||||
If not specified, debouncing is disabled.
|
||||
|
||||
drive-inactive-cols:
|
||||
type: boolean
|
||||
description: Keep direction of inactive columns as output
|
||||
|
||||
col-gpios:
|
||||
minItems: 2
|
||||
maxItems: 20
|
||||
|
||||
keypad,num-rows:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Number of row lines connected to the keypad controller.
|
||||
|
||||
keypad,num-columns:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Number of column lines connected to the keypad controller.
|
||||
|
||||
pinctrl-0:
|
||||
maxItems: 1
|
||||
|
||||
pinctrl-names:
|
||||
maxItems: 1
|
||||
|
||||
row-gpios:
|
||||
minItems: 2
|
||||
maxItems: 20
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- row-gpios
|
||||
- col-gpios
|
||||
- linux,keymap
|
||||
- keypad,num-rows
|
||||
- keypad,num-columns
|
||||
|
||||
additionalProperties: true
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
gpio-keyboard {
|
||||
compatible = "gpio-fastmatrix-keyboard";
|
||||
label = "Keyboard over I2C Expander";
|
||||
row-gpios =
|
||||
<&gpioext0 0 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>,
|
||||
<&gpioext0 1 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>,
|
||||
<&gpioext0 2 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>,
|
||||
<&gpioext0 3 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>,
|
||||
<&gpioext0 4 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>,
|
||||
<&gpioext0 5 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>,
|
||||
<&gpioext0 6 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>,
|
||||
<&gpioext0 7 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
|
||||
col-gpios =
|
||||
<&gpioext0 8 GPIO_ACTIVE_LOW>,
|
||||
<&gpioext0 9 GPIO_ACTIVE_LOW>,
|
||||
<&gpioext0 10 GPIO_ACTIVE_LOW>,
|
||||
<&gpioext0 11 GPIO_ACTIVE_LOW>,
|
||||
<&gpioext0 12 GPIO_ACTIVE_LOW>,
|
||||
<&gpioext0 13 GPIO_ACTIVE_LOW>,
|
||||
<&gpioext0 14 GPIO_ACTIVE_LOW>,
|
||||
<&gpioext0 15 GPIO_ACTIVE_LOW>;
|
||||
|
||||
linux,keymap = <
|
||||
MATRIX_KEY(0, 0, KEY_F1) MATRIX_KEY(1, 0, KEY_H)
|
||||
MATRIX_KEY(2, 0, KEY_B) MATRIX_KEY(3, 0, KEY_7)
|
||||
/* ... */
|
||||
>;
|
||||
|
||||
keypad,num-rows = <8>;
|
||||
keypad,num-columns = <8>;
|
||||
};
|
||||
123
Documentation/devicetree/bindings/input/qcom,spmi-haptics.yaml
Normal file
123
Documentation/devicetree/bindings/input/qcom,spmi-haptics.yaml
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright 2020 Unisoc Inc.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/input/qcom,spmi-haptics.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Technologies Inc PMI8998 spmi haptics
|
||||
|
||||
maintainers:
|
||||
- Caleb Connolly <caleb@connolly.tech>
|
||||
|
||||
description: |
|
||||
Qualcomm SPMI haptics is a peripheral on some QTI PMICs. It supports linear resonant
|
||||
actuators and eccentric rotating mass type haptics commonly found in mobile devices.
|
||||
It supports multiple sources of wave data such as an internal buffer, direct play
|
||||
(from kernel or userspace) as well as an audio output mode.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- qcom,pmi8998-haptics
|
||||
- qcom,pmi8996-haptics
|
||||
- qcom,pmi8941-haptics
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: short circuit interrupt
|
||||
- description: play interrupt
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: short
|
||||
- const: play
|
||||
|
||||
qcom,actuator-type:
|
||||
description: |
|
||||
The type of actuator attached to the hardware.
|
||||
Allowed values are,
|
||||
0 - HAP_TYPE_LRA
|
||||
1 - HAP_TYPE_ERM
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [ 0, 1 ]
|
||||
default: 0
|
||||
|
||||
qcom,wave-shape:
|
||||
description: |
|
||||
Selects the wave shape to use.
|
||||
Allowed values are,
|
||||
0 - HAP_WAVE_SINE
|
||||
1 - HAP_WAVE_SQUARE
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [ 0, 1 ]
|
||||
default: 0
|
||||
|
||||
qcom,play-mode:
|
||||
description: |
|
||||
Selects the play mode to use.
|
||||
Allowed values are,
|
||||
0 - HAP_PLAY_DIRECT
|
||||
1 - HAP_PLAY_BUFFER
|
||||
2 - HAP_PLAY_AUDIO
|
||||
3 - HAP_PLAY_PWM
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [ 0, 1, 2, 3 ]
|
||||
default: 2
|
||||
|
||||
qcom,wave-play-rate-us:
|
||||
description: |
|
||||
Wave sample durection in microseconds, 1/f where f
|
||||
is the resonant frequency of the actuator.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 20475
|
||||
|
||||
qcom,brake-pattern:
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
description: |
|
||||
The brake pattern are the strengths of the pattern
|
||||
used to brake the haptics. Allowed values are,
|
||||
0 - 0V
|
||||
1 - Vmax/4
|
||||
2 - Vmax/2
|
||||
3 - Vmax
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
default: [0x3, 0x3, 0x2, 0x1]
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- qcom,wave-play-rate-us
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/input/qcom,spmi-haptics.h>
|
||||
|
||||
spmi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pmi8998_haptics: haptics@c000 {
|
||||
compatible = "qcom,pmi8998-haptics";
|
||||
reg = <0xc000>;
|
||||
|
||||
interrupts = <0x3 0xc0 0x0 IRQ_TYPE_EDGE_BOTH>,
|
||||
<0x3 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>;
|
||||
interrupt-names = "short", "play";
|
||||
|
||||
qcom,wave-shape = <HAP_WAVE_SINE>;
|
||||
qcom,play-mode = <HAP_PLAY_BUFFER>;
|
||||
qcom,brake-pattern = <0x3 0x3 0x2 0x1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
158
Documentation/devicetree/bindings/interconnect/qcom,msm8998.yaml
Normal file
158
Documentation/devicetree/bindings/interconnect/qcom,msm8998.yaml
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/interconnect/qcom,msm8998.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm MSM8998 Network-On-Chip interconnect
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
|
||||
- Konrad Dybcio <konrad.dybcio@somainline.org>
|
||||
|
||||
description: |
|
||||
The Qualcomm MSM8998 interconnect providers support adjusting the
|
||||
bandwidth requirements between the various NoC fabrics.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,msm8998-a1noc
|
||||
- qcom,msm8998-a2noc
|
||||
- qcom,msm8998-bimc
|
||||
- qcom,msm8998-cnoc
|
||||
- qcom,msm8998-gnoc
|
||||
- qcom,msm8998-mnoc
|
||||
- qcom,msm8998-snoc
|
||||
|
||||
'#interconnect-cells':
|
||||
const: 1
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#interconnect-cells'
|
||||
- clock-names
|
||||
- clocks
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,msm8998-mnoc
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: Bus Clock.
|
||||
- description: Bus A Clock.
|
||||
- description: CPU-NoC High-performance Bus Clock.
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: bus_a
|
||||
- const: iface
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,msm8998-a2noc
|
||||
- qcom,msm8998-bimc
|
||||
- qcom,msm8998-cnoc
|
||||
- qcom,msm8998-gnoc
|
||||
- qcom,msm8998-snoc
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: Bus Clock.
|
||||
- description: Bus A Clock.
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: bus_a
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmcc.h>
|
||||
#include <dt-bindings/clock/qcom,mmcc-msm8998.h>
|
||||
|
||||
bimc: interconnect@1008000 {
|
||||
compatible = "qcom,msm8998-bimc";
|
||||
reg = <0x01008000 0x78000>;
|
||||
#interconnect-cells = <1>;
|
||||
clock-names = "bus", "bus_a";
|
||||
clocks = <&rpmcc RPM_SMD_BIMC_CLK>,
|
||||
<&rpmcc RPM_SMD_BIMC_A_CLK>;
|
||||
};
|
||||
|
||||
cnoc: interconnect@1500000 {
|
||||
compatible = "qcom,msm8998-cnoc";
|
||||
reg = <0x01500000 0x10000>;
|
||||
#interconnect-cells = <1>;
|
||||
clock-names = "bus", "bus_a";
|
||||
clocks = <&rpmcc RPM_SMD_CNOC_CLK>,
|
||||
<&rpmcc RPM_SMD_CNOC_A_CLK>;
|
||||
};
|
||||
|
||||
snoc: interconnect@1625000 {
|
||||
compatible = "qcom,msm8998-snoc";
|
||||
reg = <0x01625000 0x6100>;
|
||||
#interconnect-cells = <1>;
|
||||
clock-names = "bus", "bus_a";
|
||||
clocks = <&rpmcc RPM_SMD_SNOC_CLK>,
|
||||
<&rpmcc RPM_SMD_SNOC_A_CLK>;
|
||||
};
|
||||
|
||||
a1noc: interconnect@1669000 {
|
||||
compatible = "qcom,msm8998-a1noc";
|
||||
reg = <0x01669000 0x5020>;
|
||||
#interconnect-cells = <1>;
|
||||
clock-names = "bus", "bus_a";
|
||||
clocks = <&rpmcc RPM_SMD_AGGR1_NOC_CLK>,
|
||||
<&rpmcc RPM_SMD_AGGR1_NOC_A_CLK>;
|
||||
};
|
||||
|
||||
a2noc: interconnect@1705000 {
|
||||
compatible = "qcom,msm8998-a2noc";
|
||||
reg = <0x01705000 0xa090>;
|
||||
#interconnect-cells = <1>;
|
||||
clock-names = "bus", "bus_a";
|
||||
clocks = <&rpmcc RPM_SMD_AGGR2_NOC_CLK>,
|
||||
<&rpmcc RPM_SMD_AGGR2_NOC_A_CLK>;
|
||||
};
|
||||
|
||||
mnoc: interconnect@1744000 {
|
||||
compatible = "qcom,msm8998-mnoc";
|
||||
reg = <0x01744000 0xb010>;
|
||||
#interconnect-cells = <1>;
|
||||
clock-names = "bus", "bus_a", "iface";
|
||||
clocks = <&rpmcc RPM_SMD_MMAXI_CLK>,
|
||||
<&rpmcc RPM_SMD_MMAXI_A_CLK>,
|
||||
<&mmcc AHB_CLK_SRC>;
|
||||
};
|
||||
|
||||
gnoc: interconnect@17900000 {
|
||||
compatible = "qcom,msm8998-gnoc";
|
||||
reg = <0x17900000 0xe000>;
|
||||
#interconnect-cells = <1>;
|
||||
clock-names = "bus", "bus_a";
|
||||
clocks = <&xo_board>, <&xo_board>;
|
||||
};
|
||||
173
Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml
Normal file
173
Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/leds/leds-qcom-lpg.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Light Pulse Generator
|
||||
|
||||
maintainers:
|
||||
- Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||
|
||||
description: >
|
||||
The Qualcomm Light Pulse Generator consists of three different hardware blocks;
|
||||
a ramp generator with lookup table, the light pulse generator and a three
|
||||
channel current sink. These blocks are found in a wide range of Qualcomm PMICs.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,pm8150b-lpg
|
||||
- qcom,pm8150l-lpg
|
||||
- qcom,pm8916-pwm
|
||||
- qcom,pm8941-lpg
|
||||
- qcom,pm8994-lpg
|
||||
- qcom,pmc8180c-lpg
|
||||
- qcom,pmi8994-lpg
|
||||
- qcom,pmi8998-lpg
|
||||
|
||||
"#pwm-cells":
|
||||
const: 2
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
qcom,power-source:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
power-source used to drive the output, as defined in the datasheet.
|
||||
Should be specified if the TRILED block is present
|
||||
enum: [0, 1, 3]
|
||||
|
||||
qcom,dtest:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-matrix
|
||||
description: >
|
||||
A list of integer pairs, where each pair represent the dtest line the
|
||||
particular channel should be connected to and the flags denoting how the
|
||||
value should be outputed, as defined in the datasheet. The number of
|
||||
pairs should be the same as the number of channels.
|
||||
items:
|
||||
items:
|
||||
- description: dtest line to attach
|
||||
- description: flags for the attachment
|
||||
|
||||
multi-led:
|
||||
type: object
|
||||
$ref: leds-class-multicolor.yaml#
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
patternProperties:
|
||||
"^led@[0-9a-f]$":
|
||||
type: object
|
||||
$ref: common.yaml#
|
||||
|
||||
patternProperties:
|
||||
"^led@[0-9a-f]$":
|
||||
type: object
|
||||
$ref: common.yaml#
|
||||
|
||||
properties:
|
||||
reg: true
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
led-controller {
|
||||
compatible = "qcom,pmi8994-lpg";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
qcom,power-source = <1>;
|
||||
|
||||
qcom,dtest = <0 0>,
|
||||
<0 0>,
|
||||
<0 0>,
|
||||
<4 1>;
|
||||
|
||||
led@1 {
|
||||
reg = <1>;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_INDICATOR;
|
||||
function-enumerator = <1>;
|
||||
};
|
||||
|
||||
led@2 {
|
||||
reg = <2>;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_INDICATOR;
|
||||
function-enumerator = <0>;
|
||||
default-state = "on";
|
||||
};
|
||||
|
||||
led@3 {
|
||||
reg = <3>;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_INDICATOR;
|
||||
function-enumerator = <2>;
|
||||
};
|
||||
|
||||
led@4 {
|
||||
reg = <4>;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_INDICATOR;
|
||||
function-enumerator = <3>;
|
||||
};
|
||||
};
|
||||
- |
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
led-controller {
|
||||
compatible = "qcom,pmi8994-lpg";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
qcom,power-source = <1>;
|
||||
|
||||
multi-led {
|
||||
color = <LED_COLOR_ID_RGB>;
|
||||
function = LED_FUNCTION_STATUS;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led@1 {
|
||||
reg = <1>;
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
};
|
||||
|
||||
led@2 {
|
||||
reg = <2>;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
};
|
||||
|
||||
led@3 {
|
||||
reg = <3>;
|
||||
color = <LED_COLOR_ID_BLUE>;
|
||||
};
|
||||
};
|
||||
};
|
||||
- |
|
||||
pwm-controller {
|
||||
compatible = "qcom,pm8916-pwm";
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
...
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/pinctrl/awinic,aw9523-pinctrl.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Awinic AW9523/AW9523B I2C GPIO Expander
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
|
||||
|
||||
description: |
|
||||
The Awinic AW9523/AW9523B I2C GPIO Expander featuring 16 multi-function
|
||||
I/O, 256 steps PWM mode and interrupt support.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: awinic,aw9523-pinctrl
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#gpio-cells':
|
||||
description: |
|
||||
Specifying the pin number and flags, as defined in
|
||||
include/dt-bindings/gpio/gpio.h
|
||||
const: 2
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
gpio-ranges:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
description: Specifies the INTN pin IRQ.
|
||||
|
||||
'#interrupt-cells':
|
||||
description:
|
||||
Specifies the PIN numbers and Flags, as defined in defined in
|
||||
include/dt-bindings/interrupt-controller/irq.h
|
||||
const: 2
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
|
||||
#PIN CONFIGURATION NODES
|
||||
patternProperties:
|
||||
'-pins$':
|
||||
type: object
|
||||
description:
|
||||
Pinctrl node's client devices use subnodes for desired pin configuration.
|
||||
Client device subnodes use below standard properties.
|
||||
$ref: "/schemas/pinctrl/pincfg-node.yaml"
|
||||
|
||||
properties:
|
||||
pins:
|
||||
description:
|
||||
List of gpio pins affected by the properties specified in
|
||||
this subnode.
|
||||
items:
|
||||
pattern: "^gpio([0-9]|1[0-5])$"
|
||||
minItems: 1
|
||||
maxItems: 16
|
||||
|
||||
function:
|
||||
description:
|
||||
Specify the alternative function to be configured for the
|
||||
specified pins.
|
||||
|
||||
enum: [ gpio, pwm ]
|
||||
|
||||
bias-disable: true
|
||||
bias-pull-down: true
|
||||
bias-pull-up: true
|
||||
drive-open-drain: true
|
||||
drive-push-pull: true
|
||||
input-enable: true
|
||||
input-disable: true
|
||||
output-high: true
|
||||
output-low: true
|
||||
|
||||
required:
|
||||
- pins
|
||||
- function
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- gpio-controller
|
||||
- '#gpio-cells'
|
||||
- gpio-ranges
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
# Example configuration to drive pins for a keyboard matrix
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
aw9523: gpio-expander@58 {
|
||||
compatible = "awinic,aw9523-pinctrl";
|
||||
reg = <0x58>;
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <50 IRQ_TYPE_EDGE_FALLING>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
gpio-ranges = <&tlmm 0 0 16>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
reset-gpios = <&tlmm 51 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
keyboard-matrix-col-pins {
|
||||
pins = "gpio8", "gpio9", "gpio10", "gpio11",
|
||||
"gpio12", "gpio13", "gpio14", "gpio15";
|
||||
function = "gpio";
|
||||
input-disable;
|
||||
output-low;
|
||||
};
|
||||
|
||||
keyboard-matrix-row-pins {
|
||||
pins = "gpio0", "gpio1", "gpio2", "gpio3",
|
||||
"gpio4", "gpio5", "gpio6", "gpio7";
|
||||
function = "gpio";
|
||||
bias-pull-up;
|
||||
drive-open-drain;
|
||||
input-enable;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/power/supply/qcom,pmi8998-charger.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm PMI8998/PM660 Switch-Mode Battery Charger "2"
|
||||
|
||||
maintainers:
|
||||
- Caleb Connolly <caleb.connolly@linaro.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,pmi8998-charger
|
||||
- qcom,pm660-charger
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 4
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: usb-plugin
|
||||
- const: bat-ov
|
||||
- const: wdog-bark
|
||||
- const: usbin-icl-change
|
||||
|
||||
io-channels:
|
||||
items:
|
||||
- description: USB in current in uA
|
||||
- description: USB in voltage in uV
|
||||
|
||||
io-channel-names:
|
||||
items:
|
||||
- const: usbin_i
|
||||
- const: usbin_v
|
||||
|
||||
monitored-battery:
|
||||
description: phandle to the simple-battery node
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- io-channels
|
||||
- io-channel-names
|
||||
- monitored-battery
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
pmic {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#interrupt-cells = <4>;
|
||||
|
||||
charger@1000 {
|
||||
compatible = "qcom,pmi8998-charger";
|
||||
reg = <0x1000>;
|
||||
|
||||
interrupts = <0x2 0x12 0x2 IRQ_TYPE_EDGE_BOTH>,
|
||||
<0x2 0x13 0x4 IRQ_TYPE_EDGE_BOTH>,
|
||||
<0x2 0x13 0x6 IRQ_TYPE_EDGE_RISING>,
|
||||
<0x2 0x16 0x1 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "usb-plugin", "bat-ov", "wdog-bark", "usbin-icl-change";
|
||||
|
||||
io-channels = <&pmi8998_rradc 3>,
|
||||
<&pmi8998_rradc 4>;
|
||||
io-channel-names = "usbin_i",
|
||||
"usbin_v";
|
||||
|
||||
monitored-battery = <&battery>;
|
||||
};
|
||||
};
|
||||
241
Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
Normal file
241
Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/soc/qcom/qcom,cpr3.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: Qualcomm Core Power Reduction v3/v4/Hardened (CPR3, CPR4, CPRh)
|
||||
|
||||
description: |
|
||||
CPR (Core Power Reduction) is a technology to reduce core power on a CPU
|
||||
or other device. Each OPP of a device corresponds to a "corner" that has
|
||||
a range of valid voltages for a particular frequency. While the device is
|
||||
running at a particular frequency, CPR monitors dynamic factors such as
|
||||
temperature, etc. and suggests or, in the CPR-Hardened case performs,
|
||||
adjustments to the voltage to save power and meet silicon characteristic
|
||||
requirements.
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- description: CPRv3 controller
|
||||
items:
|
||||
- const: qcom,cpr3
|
||||
- description: CPRv4 controller
|
||||
items:
|
||||
- const: qcom,cpr4
|
||||
- description: CPRv4-Hardened controller
|
||||
items:
|
||||
- enum:
|
||||
- qcom,msm8998-cprh
|
||||
- qcom,sdm630-cprh
|
||||
- const: qcom,cprh
|
||||
|
||||
reg:
|
||||
description: Base address and size of the CPR controller(s)
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: "ref"
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: CPR reference clock
|
||||
|
||||
vdd-supply:
|
||||
description: Autonomous Phase Control (APC) or other power supply
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
||||
acc-syscon:
|
||||
description: phandle to syscon for writing ACC settings
|
||||
|
||||
nvmem-cells:
|
||||
description: Cells containing the fuse corners and revision data
|
||||
minItems: 10
|
||||
maxItems: 32
|
||||
|
||||
nvmem-cell-names:
|
||||
minItems: 10
|
||||
maxItems: 32
|
||||
|
||||
operating-points-v2: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clock-names
|
||||
- clocks
|
||||
- "#power-domain-cells"
|
||||
- nvmem-cells
|
||||
- nvmem-cell-names
|
||||
- operating-points-v2
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-msm8998.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
cpus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
compatible = "qcom,kryo280";
|
||||
device_type = "cpu";
|
||||
reg = <0x0 0x0>;
|
||||
operating-points-v2 = <&cpu_gold_opp_table>;
|
||||
power-domains = <&apc_cprh 0>;
|
||||
power-domain-names = "cprh";
|
||||
};
|
||||
|
||||
cpu@100 {
|
||||
compatible = "qcom,kryo280";
|
||||
device_type = "cpu";
|
||||
reg = <0x0 0x0>;
|
||||
operating-points-v2 = <&cpu_silver_opp_table>;
|
||||
power-domains = <&apc_cprh 1>;
|
||||
power-domain-names = "cprh";
|
||||
};
|
||||
};
|
||||
|
||||
cpu_silver_opp_table: cpu-silver-opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
opp-shared;
|
||||
|
||||
opp-1843200000 {
|
||||
opp-hz = /bits/ 64 <1843200000>;
|
||||
required-opps = <&cprh_opp3>;
|
||||
};
|
||||
opp-1094400000 {
|
||||
opp-hz = /bits/ 64 <1094400000>;
|
||||
required-opps = <&cprh_opp2>;
|
||||
};
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
required-opps = <&cprh_opp1>;
|
||||
};
|
||||
};
|
||||
|
||||
cpu_gold_opp_table: cpu-gold-opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
opp-shared;
|
||||
|
||||
opp-2208000000 {
|
||||
opp-hz = /bits/ 64 <2208000000>;
|
||||
required-opps = <&cprh_opp3>;
|
||||
};
|
||||
opp-1113600000 {
|
||||
opp-hz = /bits/ 64 <1113600000>;
|
||||
required-opps = <&cprh_opp2>;
|
||||
};
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
required-opps = <&cprh_opp1>;
|
||||
};
|
||||
};
|
||||
|
||||
cprh_opp_table: cpr-hardened-opp-table {
|
||||
compatible = "operating-points-v2-qcom-level";
|
||||
|
||||
cprh_opp1: opp1 {
|
||||
opp-level = <1>;
|
||||
qcom,opp-fuse-level = <1>;
|
||||
};
|
||||
cprh_opp2: opp2 {
|
||||
opp-level = <2>;
|
||||
qcom,opp-fuse-level = <2>;
|
||||
};
|
||||
cprh_opp3: opp3 {
|
||||
opp-level = <3>;
|
||||
qcom,opp-fuse-level = <2 3>;
|
||||
};
|
||||
};
|
||||
|
||||
apc_cprh: power-controller@179c8000 {
|
||||
compatible = "qcom,msm8998-cprh", "qcom,cprh";
|
||||
reg = <0x0179c8000 0x4000>, <0x0179c4000 0x4000>;
|
||||
clocks = <&gcc GCC_HMSS_RBCPR_CLK>;
|
||||
clock-names = "ref";
|
||||
|
||||
#power-domain-cells = <1>;
|
||||
operating-points-v2 = <&cprh_opp_table>;
|
||||
|
||||
nvmem-cells = <&cpr_efuse_speedbin>,
|
||||
<&cpr_fuse_revision>,
|
||||
<&cpr_quot0_pwrcl>,
|
||||
<&cpr_quot1_pwrcl>,
|
||||
<&cpr_quot2_pwrcl>,
|
||||
<&cpr_quot3_pwrcl>,
|
||||
<&cpr_quot_offset1_pwrcl>,
|
||||
<&cpr_quot_offset2_pwrcl>,
|
||||
<&cpr_quot_offset3_pwrcl>,
|
||||
<&cpr_init_voltage0_pwrcl>,
|
||||
<&cpr_init_voltage1_pwrcl>,
|
||||
<&cpr_init_voltage2_pwrcl>,
|
||||
<&cpr_init_voltage3_pwrcl>,
|
||||
<&cpr_ro_sel0_pwrcl>,
|
||||
<&cpr_ro_sel1_pwrcl>,
|
||||
<&cpr_ro_sel2_pwrcl>,
|
||||
<&cpr_ro_sel3_pwrcl>,
|
||||
<&cpr_quot0_perfcl>,
|
||||
<&cpr_quot1_perfcl>,
|
||||
<&cpr_quot2_perfcl>,
|
||||
<&cpr_quot3_perfcl>,
|
||||
<&cpr_quot_offset1_perfcl>,
|
||||
<&cpr_quot_offset2_perfcl>,
|
||||
<&cpr_quot_offset3_perfcl>,
|
||||
<&cpr_init_voltage0_perfcl>,
|
||||
<&cpr_init_voltage1_perfcl>,
|
||||
<&cpr_init_voltage2_perfcl>,
|
||||
<&cpr_init_voltage3_perfcl>,
|
||||
<&cpr_ro_sel0_perfcl>,
|
||||
<&cpr_ro_sel1_perfcl>,
|
||||
<&cpr_ro_sel2_perfcl>,
|
||||
<&cpr_ro_sel3_perfcl>;
|
||||
|
||||
nvmem-cell-names = "cpr_speed_bin",
|
||||
"cpr_fuse_revision",
|
||||
"cpr0_quotient1",
|
||||
"cpr0_quotient2",
|
||||
"cpr0_quotient3",
|
||||
"cpr0_quotient4",
|
||||
"cpr0_quotient_offset2",
|
||||
"cpr0_quotient_offset3",
|
||||
"cpr0_quotient_offset4",
|
||||
"cpr0_init_voltage1",
|
||||
"cpr0_init_voltage2",
|
||||
"cpr0_init_voltage3",
|
||||
"cpr0_init_voltage4",
|
||||
"cpr0_ring_osc1",
|
||||
"cpr0_ring_osc2",
|
||||
"cpr0_ring_osc3",
|
||||
"cpr0_ring_osc4",
|
||||
"cpr1_quotient1",
|
||||
"cpr1_quotient2",
|
||||
"cpr1_quotient3",
|
||||
"cpr1_quotient4",
|
||||
"cpr1_quotient_offset2",
|
||||
"cpr1_quotient_offset3",
|
||||
"cpr1_quotient_offset4",
|
||||
"cpr1_init_voltage1",
|
||||
"cpr1_init_voltage2",
|
||||
"cpr1_init_voltage3",
|
||||
"cpr1_init_voltage4",
|
||||
"cpr1_ring_osc1",
|
||||
"cpr1_ring_osc2",
|
||||
"cpr1_ring_osc3",
|
||||
"cpr1_ring_osc4";
|
||||
};
|
||||
...
|
||||
|
|
@ -22,19 +22,7 @@ board specific bus parameters.
|
|||
- interrupts:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should specify the SoundWire Controller core and optional
|
||||
wake IRQ
|
||||
|
||||
- interrupt-names:
|
||||
Usage: Optional
|
||||
Value type: boolean
|
||||
Value type: <stringlist>
|
||||
Definition: should be "core" for core and "wakeup" for wake interrupt.
|
||||
|
||||
- wakeup-source:
|
||||
Usage: Optional
|
||||
Value type: boolean
|
||||
Definition: should specify if SoundWire Controller is wake up capable.
|
||||
Definition: should specify the SoundWire Controller IRQ
|
||||
|
||||
- clock-names:
|
||||
Usage: required
|
||||
|
|
|
|||
76
Documentation/leds/leds-qcom-lpg.rst
Normal file
76
Documentation/leds/leds-qcom-lpg.rst
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
==============================
|
||||
Kernel driver for Qualcomm LPG
|
||||
==============================
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The Qualcomm LPG can be found in a variety of Qualcomm PMICs and consists of a
|
||||
number of PWM channels, a programmable pattern lookup table and a RGB LED
|
||||
current sink.
|
||||
|
||||
To facilitate the various use cases, the LPG channels can be exposed as
|
||||
individual LEDs, grouped together as RGB LEDs or otherwise be accessed as PWM
|
||||
channels. The output of each PWM channel is routed to other hardware
|
||||
blocks, such as the RGB current sink, GPIO pins etc.
|
||||
|
||||
The each PWM channel can operate with a period between 27us and 384 seconds and
|
||||
has a 9 bit resolution of the duty cycle.
|
||||
|
||||
In order to provide support for status notifications with the CPU subsystem in
|
||||
deeper idle states the LPG provides pattern support. This consists of a shared
|
||||
lookup table of brightness values and per channel properties to select the
|
||||
range within the table to use, the rate and if the pattern should repeat.
|
||||
|
||||
The pattern for a channel can be programmed using the "pattern" trigger, using
|
||||
the hw_pattern attribute.
|
||||
|
||||
/sys/class/leds/<led>/hw_pattern
|
||||
--------------------------------
|
||||
|
||||
Specify a hardware pattern for a Qualcomm LPG LED.
|
||||
|
||||
The pattern is a series of brightness and hold-time pairs, with the hold-time
|
||||
expressed in milliseconds. The hold time is a property of the pattern and must
|
||||
therefor be identical for each element in the pattern (except for the pauses
|
||||
described below).
|
||||
|
||||
Simple pattern::
|
||||
|
||||
"255 500 0 500"
|
||||
|
||||
^
|
||||
|
|
||||
255 +----+ +----+
|
||||
| | | | ...
|
||||
0 | +----+ +----
|
||||
+---------------------->
|
||||
0 5 10 15 time (100ms)
|
||||
|
||||
The LPG supports specifying a longer hold-time for the first and last element
|
||||
in the pattern, the so called "low pause" and "high pause".
|
||||
|
||||
Low-pause pattern::
|
||||
|
||||
"255 1000 0 500 255 500 0 500"
|
||||
|
||||
^
|
||||
|
|
||||
255 +--------+ +----+ +----+ +--------+
|
||||
| | | | | | | | ...
|
||||
0 | +----+ +----+ +----+ +----
|
||||
+----------------------------->
|
||||
0 5 10 15 20 25 time (100ms)
|
||||
|
||||
Similarily, the last entry can be stretched by using a higher hold-time on the
|
||||
last entry.
|
||||
|
||||
In order to save space in the shared lookup table the LPG supports "ping-pong"
|
||||
mode, in which case each run through the pattern is performed by first running
|
||||
the pattern forward, then backwards. This mode is automatically used by the
|
||||
driver when the given pattern is a palindrome. In this case the "high pause"
|
||||
denotes the wait time before the pattern is run in reverse and as such the
|
||||
specified hold-time of the middle item in the pattern is allowed to have a
|
||||
different hold-time.
|
||||
|
|
@ -16290,6 +16290,12 @@ S: Maintained
|
|||
F: Documentation/devicetree/bindings/power/avs/qcom,cpr.yaml
|
||||
F: drivers/soc/qcom/cpr.c
|
||||
|
||||
QUALCOMM CORE POWER REDUCTION v3/v4/Hardened AVS DRIVER
|
||||
M: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/soc/qcom/qcom,cpr3.yaml
|
||||
F: drivers/soc/qcom/cpr3.c
|
||||
|
||||
QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096
|
||||
M: Ilia Lin <ilia.lin@kernel.org>
|
||||
L: linux-pm@vger.kernel.org
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 18
|
||||
SUBLEVEL = 0
|
||||
SUBLEVEL = 1
|
||||
EXTRAVERSION =
|
||||
NAME = Superb Owl
|
||||
|
||||
|
|
|
|||
|
|
@ -28,5 +28,6 @@ static inline cycles_t get_cycles (void)
|
|||
__asm__ __volatile__ ("rpcc %0" : "=r"(ret));
|
||||
return ret;
|
||||
}
|
||||
#define get_cycles get_cycles
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -11,5 +11,6 @@
|
|||
|
||||
typedef unsigned long cycles_t;
|
||||
#define get_cycles() ({ cycles_t c; read_current_timer(&c) ? 0 : c; })
|
||||
#define random_get_entropy() (((unsigned long)get_cycles()) ?: random_get_entropy_fallback())
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,20 +16,22 @@
|
|||
|
||||
touchpad@15 {
|
||||
compatible = "hid-over-i2c";
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <0x7b IRQ_TYPE_LEVEL_LOW>;
|
||||
reg = <0x15>;
|
||||
hid-descr-addr = <0x0001>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&touchpad>;
|
||||
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <123 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
hid-descr-addr = <0x0001>;
|
||||
};
|
||||
|
||||
keyboard@3a {
|
||||
compatible = "hid-over-i2c";
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <0x25 IRQ_TYPE_LEVEL_LOW>;
|
||||
reg = <0x3a>;
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <37 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
hid-descr-addr = <0x0001>;
|
||||
};
|
||||
};
|
||||
|
|
@ -37,12 +39,3 @@
|
|||
&sdhc2 {
|
||||
cd-gpios = <&tlmm 95 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
touchpad: touchpad {
|
||||
config {
|
||||
pins = "gpio123";
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,13 +8,10 @@
|
|||
*/
|
||||
|
||||
#include "msm8998.dtsi"
|
||||
#include "pm8998.dtsi"
|
||||
#include "pm8005.dtsi"
|
||||
#include "pm8998.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
};
|
||||
|
||||
vph_pwr: vph-pwr-regulator {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vph_pwr";
|
||||
|
|
@ -37,6 +34,28 @@
|
|||
};
|
||||
};
|
||||
|
||||
&blsp1_uart3_on {
|
||||
rx {
|
||||
/delete-property/ bias-disable;
|
||||
/*
|
||||
* Configure a pull-up on 45 (RX). This is needed to
|
||||
* avoid garbage data when the TX pin of the Bluetooth
|
||||
* module is in tri-state (module powered off or not
|
||||
* driving the signal yet).
|
||||
*/
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
cts {
|
||||
/delete-property/ bias-disable;
|
||||
/*
|
||||
* Configure a pull-down on 47 (CTS) to match the pull
|
||||
* of the Bluetooth module.
|
||||
*/
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* The laptop FW does not appear to support the retention state as it is
|
||||
* not advertised as enabled in ACPI, and enabling it in DT can cause boot
|
||||
|
|
@ -74,6 +93,20 @@
|
|||
cpu-idle-states = <&BIG_CPU_SLEEP_1>;
|
||||
};
|
||||
|
||||
/*
|
||||
* If EFIFB is used, enabling MMCC will cause important MMSS clocks to be cleaned
|
||||
* up, because as far as Linux is concerned - they are unused. Disable it by default
|
||||
* on clamshell devices, as it will break them, unless either simplefb is configured to
|
||||
* hold a vote for these clocks, or panels are brought up properly, using drm/msm.
|
||||
*/
|
||||
&mmcc {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&mmss_smmu {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&pcie0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
|
@ -82,20 +115,16 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&pm8005_lsid1 {
|
||||
pm8005-regulators {
|
||||
compatible = "qcom,pm8005-regulators";
|
||||
&pm8005_regulators {
|
||||
vdd_s1-supply = <&vph_pwr>;
|
||||
|
||||
vdd_s1-supply = <&vph_pwr>;
|
||||
pm8005_s1: s1 { /* VDD_GFX supply */
|
||||
regulator-min-microvolt = <524000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
regulator-enable-ramp-delay = <500>;
|
||||
|
||||
pm8005_s1: s1 { /* VDD_GFX supply */
|
||||
regulator-min-microvolt = <524000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
regulator-enable-ramp-delay = <500>;
|
||||
|
||||
/* hack until we rig up the gpu consumer */
|
||||
regulator-always-on;
|
||||
};
|
||||
/* hack until we rig up the gpu consumer */
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -143,127 +172,156 @@
|
|||
regulator-min-microvolt = <1352000>;
|
||||
regulator-max-microvolt = <1352000>;
|
||||
};
|
||||
|
||||
vreg_s4a_1p8: s4 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_s5a_2p04: s5 {
|
||||
regulator-min-microvolt = <1904000>;
|
||||
regulator-max-microvolt = <2040000>;
|
||||
};
|
||||
|
||||
vreg_s7a_1p025: s7 {
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1028000>;
|
||||
};
|
||||
|
||||
vreg_l1a_0p875: l1 {
|
||||
regulator-min-microvolt = <880000>;
|
||||
regulator-max-microvolt = <880000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l2a_1p2: l2 {
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l3a_1p0: l3 {
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <1000000>;
|
||||
};
|
||||
|
||||
vreg_l5a_0p8: l5 {
|
||||
regulator-min-microvolt = <800000>;
|
||||
regulator-max-microvolt = <800000>;
|
||||
};
|
||||
|
||||
vreg_l6a_1p8: l6 {
|
||||
regulator-min-microvolt = <1808000>;
|
||||
regulator-max-microvolt = <1808000>;
|
||||
};
|
||||
|
||||
vreg_l7a_1p8: l7 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l8a_1p2: l8 {
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
};
|
||||
|
||||
vreg_l9a_1p8: l9 {
|
||||
regulator-min-microvolt = <1808000>;
|
||||
regulator-max-microvolt = <2960000>;
|
||||
};
|
||||
|
||||
vreg_l10a_1p8: l10 {
|
||||
regulator-min-microvolt = <1808000>;
|
||||
regulator-max-microvolt = <2960000>;
|
||||
};
|
||||
|
||||
vreg_l11a_1p0: l11 {
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <1000000>;
|
||||
};
|
||||
|
||||
vreg_l12a_1p8: l12 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
vreg_l13a_2p95: l13 {
|
||||
regulator-min-microvolt = <1808000>;
|
||||
regulator-max-microvolt = <2960000>;
|
||||
};
|
||||
|
||||
vreg_l14a_1p88: l14 {
|
||||
regulator-min-microvolt = <1880000>;
|
||||
regulator-max-microvolt = <1880000>;
|
||||
};
|
||||
|
||||
vreg_l15a_1p8: l15 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
vreg_l16a_2p7: l16 {
|
||||
regulator-min-microvolt = <2704000>;
|
||||
regulator-max-microvolt = <2704000>;
|
||||
};
|
||||
|
||||
vreg_l17a_1p3: l17 {
|
||||
regulator-min-microvolt = <1304000>;
|
||||
regulator-max-microvolt = <1304000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l18a_2p7: l18 {
|
||||
regulator-min-microvolt = <2704000>;
|
||||
regulator-max-microvolt = <2704000>;
|
||||
};
|
||||
|
||||
vreg_l19a_3p0: l19 {
|
||||
regulator-min-microvolt = <3008000>;
|
||||
regulator-max-microvolt = <3008000>;
|
||||
};
|
||||
|
||||
vreg_l20a_2p95: l20 {
|
||||
regulator-min-microvolt = <2960000>;
|
||||
regulator-max-microvolt = <2960000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l21a_2p95: l21 {
|
||||
regulator-min-microvolt = <2960000>;
|
||||
regulator-max-microvolt = <2960000>;
|
||||
regulator-allow-set-load;
|
||||
regulator-system-load = <800000>;
|
||||
};
|
||||
|
||||
vreg_l22a_2p85: l22 {
|
||||
regulator-min-microvolt = <2864000>;
|
||||
regulator-max-microvolt = <2864000>;
|
||||
};
|
||||
|
||||
vreg_l23a_3p3: l23 {
|
||||
regulator-min-microvolt = <3312000>;
|
||||
regulator-max-microvolt = <3312000>;
|
||||
};
|
||||
|
||||
vreg_l24a_3p075: l24 {
|
||||
regulator-min-microvolt = <3088000>;
|
||||
regulator-max-microvolt = <3088000>;
|
||||
};
|
||||
|
||||
vreg_l25a_3p3: l25 {
|
||||
regulator-min-microvolt = <3104000>;
|
||||
regulator-max-microvolt = <3312000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l26a_1p2: l26 {
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
};
|
||||
|
||||
vreg_l28_3p0: l28 {
|
||||
regulator-min-microvolt = <3008000>;
|
||||
regulator-max-microvolt = <3008000>;
|
||||
|
|
@ -278,7 +336,6 @@
|
|||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -286,17 +343,6 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
gpio-reserved-ranges = <0 4>, <81 4>;
|
||||
|
||||
touchpad: touchpad {
|
||||
config {
|
||||
pins = "gpio123";
|
||||
bias-pull-up; /* pull up */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&sdhc2 {
|
||||
status = "okay";
|
||||
|
||||
|
|
@ -304,8 +350,17 @@
|
|||
vqmmc-supply = <&vreg_l13a_2p95>;
|
||||
|
||||
pinctrl-names = "default", "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>;
|
||||
pinctrl-0 = <&sdc2_on &sdc2_cd>;
|
||||
pinctrl-1 = <&sdc2_off &sdc2_cd>;
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
gpio-reserved-ranges = <0 4>, <81 4>;
|
||||
|
||||
touchpad: touchpad-pin {
|
||||
pins = "gpio123";
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
&ufshc {
|
||||
|
|
@ -341,26 +396,3 @@
|
|||
vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
|
||||
vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
|
||||
};
|
||||
|
||||
/* PINCTRL - board-specific pinctrl */
|
||||
&blsp1_uart3_on {
|
||||
rx {
|
||||
/delete-property/ bias-disable;
|
||||
/*
|
||||
* Configure a pull-up on 45 (RX). This is needed to
|
||||
* avoid garbage data when the TX pin of the Bluetooth
|
||||
* module is in tri-state (module powered off or not
|
||||
* driving the signal yet).
|
||||
*/
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
cts {
|
||||
/delete-property/ bias-disable;
|
||||
/*
|
||||
* Configure a pull-down on 47 (CTS) to match the pull
|
||||
* of the Bluetooth module.
|
||||
*/
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -18,6 +18,15 @@
|
|||
chassis-type = "handset";
|
||||
qcom,board-id = <0x02000b 0x10>;
|
||||
|
||||
/* This part enables graphical output via bootloader-enabled display */
|
||||
chosen {
|
||||
bootargs = "earlycon=tty0 console=tty0 clk_ignore_unused";
|
||||
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
};
|
||||
|
||||
/*
|
||||
* Until we hook up type-c detection, we
|
||||
* have to stick with this. But it works.
|
||||
|
|
@ -46,6 +55,8 @@
|
|||
gpio-kb-extra-keys {
|
||||
compatible = "gpio-keys";
|
||||
label = "Keyboard extra keys";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&gpio_kb_pins_extra>;
|
||||
|
||||
|
|
@ -98,6 +109,39 @@
|
|||
};
|
||||
};
|
||||
|
||||
gpio_keyboard: gpio-keyboard {
|
||||
compatible = "gpio-fastmatrix-keyboard";
|
||||
label = "F(x)Tec Pro1 Hardware Keyboard";
|
||||
row-gpios =
|
||||
<&gpioext0 0 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>,
|
||||
<&gpioext0 1 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>,
|
||||
<&gpioext0 2 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>,
|
||||
<&gpioext0 3 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>,
|
||||
<&gpioext0 4 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>,
|
||||
<&gpioext0 5 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>,
|
||||
<&gpioext0 6 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>,
|
||||
<&gpioext0 7 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
|
||||
|
||||
col-gpios =
|
||||
<&gpioext0 8 GPIO_ACTIVE_LOW>,
|
||||
<&gpioext0 9 GPIO_ACTIVE_LOW>,
|
||||
<&gpioext0 10 GPIO_ACTIVE_LOW>,
|
||||
<&gpioext0 11 GPIO_ACTIVE_LOW>,
|
||||
<&gpioext0 12 GPIO_ACTIVE_LOW>,
|
||||
<&gpioext0 13 GPIO_ACTIVE_LOW>,
|
||||
<&gpioext0 14 GPIO_ACTIVE_LOW>,
|
||||
<&gpioext0 15 GPIO_ACTIVE_LOW>;
|
||||
keypad,num-rows = <8>;
|
||||
keypad,num-columns = <8>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&keyboard_pins_col>, <&keyboard_pins_row>;
|
||||
|
||||
autorescan-ms = <5>;
|
||||
debounce-delay-ms = <1>;
|
||||
col-scan-delay-us = <1500>;
|
||||
};
|
||||
|
||||
gpio-keys {
|
||||
compatible = "gpio-keys";
|
||||
label = "Side buttons";
|
||||
|
|
@ -177,6 +221,53 @@
|
|||
};
|
||||
};
|
||||
|
||||
disp_vcc_vreg: disp-vcc-regulator {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "disp_vcc";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
disp_vddio_vreg: disp-vddio-regulator {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "disp_vddio";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
disp_vci_vreg: disp-vci-regulator {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "disp_vci";
|
||||
regulator-min-microvolt = <3000000>;
|
||||
regulator-max-microvolt = <3000000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
disp_elvdd_vreg: disp-elvdd-regulator {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "disp_elvdd";
|
||||
regulator-min-microvolt = <4600000>;
|
||||
regulator-max-microvolt = <4600000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
disp_elvss_vreg: disp-elvss-regulator {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "disp_elvss";
|
||||
regulator-min-microvolt = <2400000>;
|
||||
regulator-max-microvolt = <2400000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ts_vio_vreg: ts-vio-vreg {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "ts_vio_reg";
|
||||
|
|
@ -189,8 +280,62 @@
|
|||
};
|
||||
};
|
||||
|
||||
&adreno_gpu {
|
||||
status = "okay";
|
||||
|
||||
zap-shader {
|
||||
memory-region = <&zap_shader_region>;
|
||||
firmware-name = "qcom/a540_zap.mbn";
|
||||
};
|
||||
};
|
||||
|
||||
&adreno_smmu {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&apc_cprh {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&blsp1_i2c6 {
|
||||
status = "okay";
|
||||
|
||||
gpioext0: gpio-expander@58 {
|
||||
compatible = "awinic,aw9523-pinctrl";
|
||||
reg = <0x58>;
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <50 IRQ_TYPE_EDGE_FALLING>;
|
||||
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
gpio-ranges = <&gpioext0 0 0 16>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
pinctrl-0 = <&gpio_expander_int_n>, <&gpio_expander_rst_n>;
|
||||
pinctrl-names = "default";
|
||||
reset-gpios = <&tlmm 51 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
keyboard_pins_col: keyboard-matrix-col-pins {
|
||||
pins = "gpio8", "gpio9", "gpio10", "gpio11",
|
||||
"gpio12", "gpio13", "gpio14", "gpio15";
|
||||
function = "gpio";
|
||||
output-low;
|
||||
};
|
||||
keyboard_pins_row: keyboard-matrix-row-pins {
|
||||
pins = "gpio0", "gpio1", "gpio2", "gpio3",
|
||||
"gpio4", "gpio5", "gpio6", "gpio7";
|
||||
function = "gpio";
|
||||
drive-open-drain;
|
||||
input-enable;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&blsp2_i2c1 {
|
||||
status = "ok";
|
||||
status = "okay";
|
||||
qcom,noise-reject-scl = <3>;
|
||||
qcom,noise-reject-sda = <3>;
|
||||
|
||||
touchscreen@14 {
|
||||
compatible = "goodix,gt9286";
|
||||
|
|
@ -205,15 +350,141 @@
|
|||
};
|
||||
};
|
||||
|
||||
&mmcc {
|
||||
status = "ok";
|
||||
&cpufreq_hw {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mmss_smmu {
|
||||
status = "ok";
|
||||
&dsi0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "okay";
|
||||
|
||||
vdd-supply = <&vreg_l1a_0p875>;
|
||||
vdda-supply = <&vreg_l2a_1p2>;
|
||||
|
||||
panel: panel@0 {
|
||||
compatible = "boe,bf060y8m-aj0";
|
||||
reg = <0>;
|
||||
|
||||
reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
|
||||
disp-te-gpios = <&tlmm 10 GPIO_ACTIVE_LOW>;
|
||||
no-hpd;
|
||||
|
||||
vcc-supply = <&disp_vcc_vreg>;
|
||||
vddio-supply = <&disp_vddio_vreg>;
|
||||
vci-supply = <&disp_vci_vreg>;
|
||||
elvdd-supply = <&disp_elvdd_vreg>;
|
||||
elvss-supply = <&disp_elvss_vreg>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&panel_reset_n &disp_en_default &mdp_vsync_n>;
|
||||
port {
|
||||
panel_in: endpoint {
|
||||
remote-endpoint = <&dsi0_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&dsi0_phy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&dsi0_out {
|
||||
remote-endpoint = <&panel_in>;
|
||||
data-lanes = <0 1 2 3>;
|
||||
};
|
||||
|
||||
&gcc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpucc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio_keyboard {
|
||||
linux,keymap = <
|
||||
MATRIX_KEY(0, 0, KEY_F1) MATRIX_KEY(1, 0, KEY_H)
|
||||
MATRIX_KEY(2, 0, KEY_B) MATRIX_KEY(3, 0, KEY_7)
|
||||
MATRIX_KEY(4, 0, KEY_UP) MATRIX_KEY(5, 0, KEY_ENTER)
|
||||
MATRIX_KEY(6, 0, KEY_Y) MATRIX_KEY(7, 0, KEY_COMMA)
|
||||
MATRIX_KEY(0, 1, KEY_3) MATRIX_KEY(1, 1, KEY_S)
|
||||
MATRIX_KEY(2, 1, KEY_Z) MATRIX_KEY(3, 1, KEY_M)
|
||||
MATRIX_KEY(4, 1, KEY_I) MATRIX_KEY(5, 1, KEY_9)
|
||||
MATRIX_KEY(6, 1, KEY_W) MATRIX_KEY(7, 1, KEY_J)
|
||||
MATRIX_KEY(0, 2, KEY_LEFT) MATRIX_KEY(1, 2, KEY_G)
|
||||
MATRIX_KEY(2, 2, KEY_V) MATRIX_KEY(3, 2, KEY_6)
|
||||
MATRIX_KEY(4, 2, KEY_RIGHT) MATRIX_KEY(5, 2, KEY_DELETE)
|
||||
MATRIX_KEY(6, 2, KEY_T) MATRIX_KEY(7, 2, KEY_DOT)
|
||||
MATRIX_KEY(0, 3, KEY_SLASH) MATRIX_KEY(1, 3, KEY_A)
|
||||
MATRIX_KEY(2, 3, KEY_RIGHTBRACE) MATRIX_KEY(3, 3, KEY_HOMEPAGE)
|
||||
MATRIX_KEY(4, 3, KEY_P) MATRIX_KEY(5, 3, KEY_MINUS)
|
||||
MATRIX_KEY(6, 3, KEY_Q) MATRIX_KEY(7, 3, KEY_L)
|
||||
MATRIX_KEY(0, 4, KEY_BACKSPACE) MATRIX_KEY(1, 4, KEY_D)
|
||||
MATRIX_KEY(2, 4, KEY_X) MATRIX_KEY(3, 4, KEY_K)
|
||||
MATRIX_KEY(4, 4, KEY_SEMICOLON) MATRIX_KEY(5, 4, KEY_EQUAL)
|
||||
MATRIX_KEY(6, 4, KEY_E) MATRIX_KEY(7, 4, KEY_APOSTROPHE)
|
||||
MATRIX_KEY(0, 5, KEY_CAPSLOCK) MATRIX_KEY(1, 5, KEY_BACKSLASH)
|
||||
MATRIX_KEY(2, 5, KEY_LEFTBRACE) MATRIX_KEY(3, 5, KEY_DOWN)
|
||||
MATRIX_KEY(4, 5, KEY_O) MATRIX_KEY(5, 5, KEY_0)
|
||||
MATRIX_KEY(6, 5, KEY_GRAVE) MATRIX_KEY(7, 5, KEY_K)
|
||||
MATRIX_KEY(0, 6, KEY_SPACE) MATRIX_KEY(1, 6, KEY_F)
|
||||
MATRIX_KEY(2, 6, KEY_C) MATRIX_KEY(3, 6, KEY_N)
|
||||
MATRIX_KEY(4, 6, KEY_U) MATRIX_KEY(5, 6, KEY_8)
|
||||
MATRIX_KEY(6, 6, KEY_R) MATRIX_KEY(7, 6, KEY_5)
|
||||
MATRIX_KEY(0, 7, KEY_ESC) MATRIX_KEY(1, 7, KEY_1)
|
||||
MATRIX_KEY(2, 7, KEY_RESERVED) MATRIX_KEY(3, 7, KEY_RESERVED)
|
||||
MATRIX_KEY(4, 7, KEY_2) MATRIX_KEY(5, 7, KEY_4)
|
||||
MATRIX_KEY(6, 7, KEY_TAB) MATRIX_KEY(7, 7, KEY_RESERVED)
|
||||
>;
|
||||
};
|
||||
|
||||
&mdss {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mdss_mdp {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&remoteproc_adsp {
|
||||
status = "okay";
|
||||
|
||||
firmware-name = "qcom/msm8998/fxtec/adsp.mbn";
|
||||
};
|
||||
|
||||
&remoteproc_mss {
|
||||
firmware-name = "qcom/msm8998/fxtec/mba.mbn", "qcom/msm8998/fxtec/modem.mbn";
|
||||
};
|
||||
|
||||
&remoteproc_slpi {
|
||||
status = "okay";
|
||||
|
||||
firmware-name = "qcom/msm8998/fxtec/slpi_v2.mbn";
|
||||
};
|
||||
|
||||
&pmi8998_haptics {
|
||||
status = "okay";
|
||||
|
||||
qcom,wave-play-rate-us = <5000>;
|
||||
};
|
||||
|
||||
/* HACK! Push GPU voltage high until GPU CPR is hooked up */
|
||||
&pm8005_s1 {
|
||||
regulator-min-microvolt = <988000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
};
|
||||
|
||||
&pm8998_gpio {
|
||||
unknown_pin_a: unk-active {
|
||||
pins = "gpio5";
|
||||
function = "normal";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
|
||||
};
|
||||
|
||||
vol_up_pin_a: vol-up-active {
|
||||
pins = "gpio6";
|
||||
function = "normal";
|
||||
|
|
@ -267,6 +538,26 @@
|
|||
bias-pull-up;
|
||||
};
|
||||
|
||||
gpio_expander_int_n: gpio-exp-intn-def {
|
||||
pins = "gpio50";
|
||||
function = "gpio";
|
||||
drive-strength = <2>;
|
||||
input-enable;
|
||||
};
|
||||
|
||||
gpio_expander_rst_n: gpio-exp-rst-def {
|
||||
pins = "gpio51";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
};
|
||||
|
||||
disp_en_default: disp-en {
|
||||
pins = "gpio62";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
ts_vio_default: ts-vio-def {
|
||||
pins = "gpio81";
|
||||
function = "gpio";
|
||||
|
|
@ -295,14 +586,21 @@
|
|||
bias-disable;
|
||||
drive-strength = <8>;
|
||||
};
|
||||
|
||||
panel_reset_n: panel-rst-n {
|
||||
pins = "gpio94";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
&ufshc {
|
||||
status = "ok";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ufsphy {
|
||||
status = "ok";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb3_dwc3 {
|
||||
|
|
|
|||
|
|
@ -16,13 +16,14 @@
|
|||
|
||||
keyboard@3a {
|
||||
compatible = "hid-over-i2c";
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <0x79 IRQ_TYPE_LEVEL_LOW>;
|
||||
reg = <0x3a>;
|
||||
hid-descr-addr = <0x0001>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&touchpad>;
|
||||
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <121 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
hid-descr-addr = <0x0001>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -16,13 +16,14 @@
|
|||
|
||||
keyboard@3a {
|
||||
compatible = "hid-over-i2c";
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <0x79 IRQ_TYPE_LEVEL_LOW>;
|
||||
reg = <0x3a>;
|
||||
hid-descr-addr = <0x0001>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&touchpad>;
|
||||
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <121 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
hid-descr-addr = <0x0001>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -348,8 +348,8 @@
|
|||
vqmmc-supply = <&vreg_l13a_2p95>;
|
||||
|
||||
pinctrl-names = "default", "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>;
|
||||
pinctrl-0 = <&sdc2_on &sdc2_cd>;
|
||||
pinctrl-1 = <&sdc2_off &sdc2_cd>;
|
||||
};
|
||||
|
||||
&stm {
|
||||
|
|
|
|||
|
|
@ -41,3 +41,19 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* Capacitive keypad buttons */
|
||||
&rmi4_i2c {
|
||||
rmi4-f1a@1a {
|
||||
reg = <0x1a>;
|
||||
syna,codes = <KEY_BACK KEY_APPSELECT>;
|
||||
};
|
||||
};
|
||||
|
||||
/* Display */
|
||||
&panel {
|
||||
compatible = "samsung,s6e3fa5";
|
||||
|
||||
/* The panel is mounted upside down on the OnePlus 5 */
|
||||
rotation = <180>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,11 +9,12 @@
|
|||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
|
||||
#include "msm8998.dtsi"
|
||||
#include "pm8005.dtsi"
|
||||
#include "pm8998.dtsi"
|
||||
#include "pmi8998.dtsi"
|
||||
#include "pm8005.dtsi"
|
||||
|
||||
/ {
|
||||
/* Required for bootloader to select correct board */
|
||||
|
|
@ -32,6 +33,20 @@
|
|||
height = <1920>;
|
||||
stride = <(1080 * 4)>;
|
||||
format = "a8r8g8b8";
|
||||
/*
|
||||
* That's a lot of clocks, but it's necessary due
|
||||
* to unused clk cleanup & no panel driver yet..
|
||||
*/
|
||||
clocks = <&mmcc MDSS_AHB_CLK>,
|
||||
<&mmcc MDSS_AXI_CLK>,
|
||||
<&mmcc MDSS_VSYNC_CLK>,
|
||||
<&mmcc MDSS_MDP_CLK>,
|
||||
<&mmcc MDSS_BYTE0_CLK>,
|
||||
<&mmcc MDSS_BYTE0_INTF_CLK>,
|
||||
<&mmcc MDSS_PCLK0_CLK>,
|
||||
<&mmcc MDSS_ESC0_CLK>;
|
||||
power-domains = <&mmcc MDSS_GDSC>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -67,6 +82,15 @@
|
|||
reg = <0x0 0xf6900000 0x0 0x2000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
blp637_bat: battery {
|
||||
compatible = "simple-battery";
|
||||
voltage-max-design-microvolt = <4370000>;
|
||||
voltage-min-design-microvolt = <3700000>;
|
||||
charge-full-design-microamp-hours = <3300000>;
|
||||
energy-full-design-microwatt-hours = <12700000>;
|
||||
operating-range-celsius = <0 45>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio-keys {
|
||||
|
|
@ -152,10 +176,18 @@
|
|||
reg = <0x0 0x95715000 0x0 0x100000>;
|
||||
};
|
||||
|
||||
&apc_cprh {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cpufreq_hw {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&blsp1_i2c5 {
|
||||
status = "okay";
|
||||
|
||||
touchscreen@20 {
|
||||
rmi4_i2c: touchscreen@20 {
|
||||
compatible = "syna,rmi4-i2c";
|
||||
reg = <0x20>;
|
||||
#address-cells = <1>;
|
||||
|
|
@ -188,6 +220,29 @@
|
|||
};
|
||||
};
|
||||
|
||||
&blsp1_i2c5_sleep {
|
||||
/delete-property/ bias-pull-up;
|
||||
/* Configure a no-pull on TP I2C sleep to match downstream. */
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
&blsp1_i2c6 {
|
||||
status = "okay";
|
||||
|
||||
nfc@28 {
|
||||
compatible = "nxp,nxp-nci-i2c";
|
||||
reg = <0x28>;
|
||||
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <92 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&nfc_int_active &nfc_enable_active>;
|
||||
};
|
||||
};
|
||||
|
||||
&blsp1_uart3 {
|
||||
status = "okay";
|
||||
|
||||
|
|
@ -224,39 +279,88 @@
|
|||
};
|
||||
};
|
||||
|
||||
&blsp2_i2c1 {
|
||||
status = "okay";
|
||||
|
||||
fuel-gauge@55 {
|
||||
compatible = "ti,bq27411";
|
||||
reg = <0x55>;
|
||||
|
||||
/*
|
||||
* TODO: Adding this appears to not change any reported stats in:
|
||||
* $ cat /sys/class/power_supply/bq27411-0/uevent
|
||||
*/
|
||||
monitored-battery = <&blp637_bat>;
|
||||
};
|
||||
};
|
||||
|
||||
&blsp2_i2c3 {
|
||||
status = "disabled";
|
||||
|
||||
audio-codec@36 {
|
||||
compatible = "nxp,tfa9890";
|
||||
reg = <0x36>;
|
||||
|
||||
/*
|
||||
* vddd-supply = <&vreg_bob>;
|
||||
* vreg_l20a_2p95? 2950000->2960000 mV @ 200->800000 mA?
|
||||
*/
|
||||
|
||||
sound-name-prefix = "Mono Speaker";
|
||||
#sound-dai-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
&blsp2_uart1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pm8005_lsid1 {
|
||||
pm8005-regulators {
|
||||
compatible = "qcom,pm8005-regulators";
|
||||
&ipa {
|
||||
status = "okay";
|
||||
|
||||
vdd_s1-supply = <&vph_pwr>;
|
||||
memory-region = <&ipa_fws_region>; // ipa_fw_mem? ipa_gsi_mem?
|
||||
firmware-name = "qcom/msm8998/oneplus/ipa_fws.mbn";
|
||||
};
|
||||
|
||||
pm8005_s1: s1 { /* VDD_GFX supply */
|
||||
regulator-min-microvolt = <524000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
regulator-enable-ramp-delay = <500>;
|
||||
|
||||
/* hack until we rig up the gpu consumer */
|
||||
regulator-always-on;
|
||||
};
|
||||
&pm8005_regulators {
|
||||
/* VDD_GFX supply */
|
||||
pm8005_s1: s1 {
|
||||
regulator-min-microvolt = <524000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
regulator-enable-ramp-delay = <500>;
|
||||
/* Hack until we rig up the gpu consumer */
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
|
||||
&pm8998_gpio {
|
||||
vol_keys_default: vol-keys-default {
|
||||
pinconf {
|
||||
pins = "gpio5", "gpio6";
|
||||
function = "normal";
|
||||
bias-pull-up;
|
||||
input-enable;
|
||||
qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
|
||||
};
|
||||
pins = "gpio5", "gpio6";
|
||||
function = "normal";
|
||||
bias-pull-up;
|
||||
input-enable;
|
||||
qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
|
||||
};
|
||||
};
|
||||
|
||||
&pmi8998_haptics {
|
||||
status = "okay";
|
||||
|
||||
qcom,wave-play-rate-us = <4255>;
|
||||
};
|
||||
|
||||
&pmi8998_charger {
|
||||
status = "okay";
|
||||
|
||||
monitored-battery = <&blp637_bat>;
|
||||
};
|
||||
|
||||
// cat /sys/bus/iio/devices/iio:device0/in_current0_*
|
||||
&pmi8998_rradc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&qusb2phy {
|
||||
status = "okay";
|
||||
|
||||
|
|
@ -269,30 +373,18 @@
|
|||
pm8998-regulators {
|
||||
compatible = "qcom,rpm-pm8998-regulators";
|
||||
|
||||
vdd_s1-supply = <&vph_pwr>;
|
||||
vdd_s2-supply = <&vph_pwr>;
|
||||
vdd_s1-supply = <&vph_pwr>; /* GPU? */
|
||||
vdd_s3-supply = <&vph_pwr>;
|
||||
vdd_s4-supply = <&vph_pwr>;
|
||||
vdd_s5-supply = <&vph_pwr>;
|
||||
vdd_s6-supply = <&vph_pwr>;
|
||||
vdd_s7-supply = <&vph_pwr>;
|
||||
vdd_s8-supply = <&vph_pwr>;
|
||||
vdd_s9-supply = <&vph_pwr>;
|
||||
vdd_s10-supply = <&vph_pwr>;
|
||||
vdd_s11-supply = <&vph_pwr>;
|
||||
vdd_s12-supply = <&vph_pwr>;
|
||||
vdd_s13-supply = <&vph_pwr>;
|
||||
vdd_l1_l27-supply = <&vreg_s7a_1p025>;
|
||||
vdd_l2_l8_l17-supply = <&vreg_s3a_1p35>;
|
||||
vdd_l3_l11-supply = <&vreg_s7a_1p025>;
|
||||
vdd_l4_l5-supply = <&vreg_s7a_1p025>;
|
||||
vdd_l1-supply = <&vreg_s7a_1p025>;
|
||||
vdd_l2_l17-supply = <&vreg_s3a_1p35>;
|
||||
vdd_l5-supply = <&vreg_s7a_1p025>;
|
||||
vdd_l6-supply = <&vreg_s5a_2p04>;
|
||||
vdd_l7_l12_l14_l15-supply = <&vreg_s5a_2p04>;
|
||||
vdd_l9-supply = <&vreg_bob>;
|
||||
vdd_l10_l23_l25-supply = <&vreg_bob>;
|
||||
vdd_l13_l19_l21-supply = <&vreg_bob>;
|
||||
vdd_l16_l28-supply = <&vreg_bob>;
|
||||
vdd_l18_l22-supply = <&vreg_bob>;
|
||||
vdd_l7_l12_l14-supply = <&vreg_s5a_2p04>;
|
||||
vdd_l25-supply = <&vreg_bob>;
|
||||
vdd_l28-supply = <&vreg_bob>;
|
||||
vdd_l20_l24-supply = <&vreg_bob>;
|
||||
vdd_l26-supply = <&vreg_s3a_1p35>;
|
||||
vdd_lvs1_lvs2-supply = <&vreg_s4a_1p8>;
|
||||
|
|
@ -301,127 +393,90 @@
|
|||
regulator-min-microvolt = <1352000>;
|
||||
regulator-max-microvolt = <1352000>;
|
||||
};
|
||||
|
||||
vreg_s4a_1p8: s4 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_s5a_2p04: s5 {
|
||||
regulator-min-microvolt = <1904000>;
|
||||
regulator-max-microvolt = <2040000>;
|
||||
};
|
||||
|
||||
vreg_s7a_1p025: s7 {
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1028000>;
|
||||
};
|
||||
vreg_l1a_0p875: l1 {
|
||||
|
||||
vreg_l1a_0p875: l1 { /* UFS PHY */
|
||||
regulator-min-microvolt = <880000>;
|
||||
regulator-max-microvolt = <880000>;
|
||||
};
|
||||
vreg_l2a_1p2: l2 {
|
||||
|
||||
vreg_l2a_1p2: l2 { /* UFS PHY */
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
};
|
||||
vreg_l3a_1p0: l3 {
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <1000000>;
|
||||
};
|
||||
vreg_l5a_0p8: l5 {
|
||||
|
||||
vreg_l5a_0p8: l5 { /* Wi-Fi */
|
||||
regulator-min-microvolt = <800000>;
|
||||
regulator-max-microvolt = <800000>;
|
||||
};
|
||||
vreg_l6a_1p8: l6 {
|
||||
|
||||
vreg_l6a_1p8: l6 { /* Touchscreen */
|
||||
regulator-min-microvolt = <1808000>;
|
||||
regulator-max-microvolt = <1808000>;
|
||||
};
|
||||
vreg_l7a_1p8: l7 {
|
||||
|
||||
vreg_l7a_1p8: l7 { /* Wi-Fi + BT */
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
vreg_l8a_1p2: l8 {
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
};
|
||||
vreg_l9a_1p8: l9 {
|
||||
regulator-min-microvolt = <1808000>;
|
||||
regulator-max-microvolt = <2960000>;
|
||||
};
|
||||
vreg_l10a_1p8: l10 {
|
||||
regulator-min-microvolt = <1808000>;
|
||||
regulator-max-microvolt = <2960000>;
|
||||
};
|
||||
vreg_l11a_1p0: l11 {
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <1000000>;
|
||||
};
|
||||
vreg_l12a_1p8: l12 {
|
||||
|
||||
vreg_l12a_1p8: l12 { /* QUSB2 PHY */
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
vreg_l13a_2p95: l13 {
|
||||
regulator-min-microvolt = <1808000>;
|
||||
regulator-max-microvolt = <2960000>;
|
||||
};
|
||||
vreg_l14a_1p88: l14 {
|
||||
|
||||
vreg_l14a_1p88: l14 { /* DSI display */
|
||||
regulator-min-microvolt = <1880000>;
|
||||
regulator-max-microvolt = <1880000>;
|
||||
};
|
||||
vreg_l15a_1p8: l15 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
vreg_l16a_2p7: l16 {
|
||||
regulator-min-microvolt = <2704000>;
|
||||
regulator-max-microvolt = <2704000>;
|
||||
};
|
||||
vreg_l17a_1p3: l17 {
|
||||
|
||||
vreg_l17a_1p3: l17 { /* Wi-Fi + BT */
|
||||
regulator-min-microvolt = <1304000>;
|
||||
regulator-max-microvolt = <1304000>;
|
||||
};
|
||||
vreg_l18a_2p7: l18 {
|
||||
regulator-min-microvolt = <2704000>;
|
||||
regulator-max-microvolt = <2704000>;
|
||||
};
|
||||
vreg_l19a_3p0: l19 {
|
||||
regulator-min-microvolt = <3008000>;
|
||||
regulator-max-microvolt = <3008000>;
|
||||
};
|
||||
vreg_l20a_2p95: l20 {
|
||||
|
||||
vreg_l20a_2p95: l20 { /* UFS HC */
|
||||
regulator-min-microvolt = <2960000>;
|
||||
regulator-max-microvolt = <2960000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
vreg_l21a_2p95: l21 {
|
||||
regulator-min-microvolt = <2960000>;
|
||||
regulator-max-microvolt = <2960000>;
|
||||
regulator-allow-set-load;
|
||||
regulator-system-load = <800000>;
|
||||
};
|
||||
vreg_l22a_2p85: l22 {
|
||||
regulator-min-microvolt = <2864000>;
|
||||
regulator-max-microvolt = <2864000>;
|
||||
};
|
||||
vreg_l23a_3p3: l23 {
|
||||
regulator-min-microvolt = <3312000>;
|
||||
regulator-max-microvolt = <3312000>;
|
||||
};
|
||||
vreg_l24a_3p075: l24 {
|
||||
|
||||
vreg_l24a_3p075: l24 { /* QUSB2 PHY */
|
||||
regulator-min-microvolt = <3088000>;
|
||||
regulator-max-microvolt = <3088000>;
|
||||
};
|
||||
vreg_l25a_3p3: l25 {
|
||||
|
||||
vreg_l25a_3p3: l25 { /* Wi-Fi + BT */
|
||||
regulator-min-microvolt = <3104000>;
|
||||
regulator-max-microvolt = <3312000>;
|
||||
};
|
||||
vreg_l26a_1p2: l26 {
|
||||
|
||||
vreg_l26a_1p2: l26 { /* UFS PHY + HC */
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
vreg_l28_3p0: l28 {
|
||||
|
||||
vreg_l28_3p0: l28 { /* Touchscreen */
|
||||
regulator-min-microvolt = <3008000>;
|
||||
regulator-max-microvolt = <3008000>;
|
||||
};
|
||||
|
||||
vreg_lvs1a_1p8: lvs1 { };
|
||||
vreg_lvs2a_1p8: lvs2 { };
|
||||
};
|
||||
|
|
@ -438,9 +493,140 @@
|
|||
};
|
||||
};
|
||||
|
||||
&remoteproc_adsp {
|
||||
status = "okay";
|
||||
|
||||
firmware-name = "qcom/msm8998/oneplus/adsp.mbn";
|
||||
};
|
||||
|
||||
&remoteproc_mss {
|
||||
status = "okay";
|
||||
|
||||
firmware-name = "qcom/msm8998/oneplus/mba.mbn", "qcom/msm8998/oneplus/modem.mbn";
|
||||
};
|
||||
|
||||
&remoteproc_slpi {
|
||||
status = "okay";
|
||||
|
||||
firmware-name = "qcom/msm8998/oneplus/slpi_v2.mbn";
|
||||
};
|
||||
|
||||
&mdss {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mdss_mdp {
|
||||
status = "okay";
|
||||
|
||||
/* It appears CTL_START register always reads back as 0 */
|
||||
qcom,ctl-no-start-read-quirk;
|
||||
};
|
||||
|
||||
&dsi0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "okay";
|
||||
|
||||
vdd-supply = <&vreg_l1a_0p875>;
|
||||
vdda-supply = <&vreg_l2a_1p2>;
|
||||
|
||||
panel: panel@0 {
|
||||
reg = <0>;
|
||||
|
||||
reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
|
||||
disp-te-gpios = <&tlmm 11 GPIO_ACTIVE_LOW>;
|
||||
|
||||
vddio-supply = <&vreg_l14a_1p88>; // TODO: Could this be moved under dsi0?
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&panel_reset_n &disp_en_default &mdp_vsync_n>;
|
||||
|
||||
port {
|
||||
panel_in: endpoint {
|
||||
remote-endpoint = <&dsi0_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&dsi0_phy {
|
||||
status = "okay";
|
||||
vdds-supply = <&vreg_l1a_0p875>;
|
||||
};
|
||||
|
||||
&dsi0_out {
|
||||
remote-endpoint = <&panel_in>;
|
||||
data-lanes = <0 1 2 3>;
|
||||
};
|
||||
|
||||
/* Adreno 540 GPU */
|
||||
&gpucc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpu_mem {
|
||||
compatible = "shared-dma-pool";
|
||||
};
|
||||
|
||||
&adreno_gpu {
|
||||
status = "okay";
|
||||
|
||||
zap-shader {
|
||||
memory-region = <&zap_shader_region>; // gpu_mem?
|
||||
firmware-name = "qcom/msm8998/oneplus/a540_zap.mbn";
|
||||
};
|
||||
|
||||
/*
|
||||
* We are lacking support for the GPU regulator. Hence, disable higher
|
||||
* frequencies for now to prevent the platform from hanging on high
|
||||
* graphics loads. Perhaps the pm8005_s1 voltage below could be
|
||||
* adjusted but I'd rather not touch it.
|
||||
*/
|
||||
opp-table {
|
||||
/delete-node/ opp-710000097;
|
||||
/delete-node/ opp-670000048;
|
||||
/delete-node/ opp-596000097;
|
||||
/delete-node/ opp-515000097;
|
||||
};
|
||||
};
|
||||
|
||||
&adreno_smmu {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/*
|
||||
* HACK: Shoot GPU voltage high to stabilize Adreno 540 at high frequencies
|
||||
* until the GPU CPR is brought up.
|
||||
*/
|
||||
&pm8005_s1 {
|
||||
regulator-min-microvolt = <988000>; /* 0,524V -> 0,988V */
|
||||
//regulator-max-microvolt = <1100000>;
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
gpio-reserved-ranges = <0 4>, <81 4>;
|
||||
|
||||
disp_en_default: disp-en {
|
||||
pins = "gpio62";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
panel_reset_n: panel-rst-n {
|
||||
pins = "gpio94";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
mdp_vsync_n: mdp-vsync-n {
|
||||
pins = "gpio11";
|
||||
function = "mdp_vsync_a";
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
hall_sensor_default: hall-sensor-default {
|
||||
pins = "gpio124";
|
||||
function = "gpio";
|
||||
|
|
@ -462,6 +648,20 @@
|
|||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
nfc_int_active: nfc_int_active {
|
||||
pins = "gpio92";
|
||||
function = "gpio";
|
||||
drive-strength = <6>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
nfc_enable_active: nfc_enable_active {
|
||||
pins = "gpio12", "gpio116";
|
||||
function = "gpio";
|
||||
drive-strength = <6>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
&ufshc {
|
||||
|
|
@ -503,7 +703,7 @@
|
|||
};
|
||||
|
||||
&wifi {
|
||||
/* Leave disabled until MSS is functional */
|
||||
status = "okay";
|
||||
vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>;
|
||||
vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
|
||||
vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
|
||||
|
|
|
|||
|
|
@ -24,3 +24,8 @@
|
|||
&rmi4_f12 {
|
||||
touchscreen-y-mm = <137>;
|
||||
};
|
||||
|
||||
/* Display */
|
||||
&panel {
|
||||
compatible = "samsung,s6e3fc1";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,7 +25,16 @@
|
|||
qcom,soft-start-us = <800>;
|
||||
};
|
||||
|
||||
&wcd9335 {
|
||||
pinctrl-0 = <&cdc_reset_n &wcd_int_n>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
&vreg_l22a_2p85 {
|
||||
regulator-min-microvolt = <2800000>;
|
||||
regulator-max-microvolt = <2800000>;
|
||||
};
|
||||
|
||||
&vreg_lvs1a_1p8 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,6 +26,28 @@
|
|||
};
|
||||
};
|
||||
|
||||
&dsi0 {
|
||||
qcom,dual-dsi-mode;
|
||||
qcom,master-dsi;
|
||||
};
|
||||
|
||||
&dsi1 {
|
||||
vdd-supply = <&vreg_l1a_0p875>;
|
||||
vdda-supply = <&vreg_l2a_1p2>;
|
||||
qcom,dual-dsi-mode;
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&dsi1_out {
|
||||
remote-endpoint = <&panel_in1>;
|
||||
data-lanes = <0 1 2 3>;
|
||||
};
|
||||
|
||||
&dsi1_phy {
|
||||
vdds-supply = <&vreg_l1a_0p875>;
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&ibb {
|
||||
regulator-min-microvolt = <5600000>;
|
||||
regulator-max-microvolt = <5600000>;
|
||||
|
|
@ -37,6 +59,32 @@
|
|||
qcom,soft-start-us = <200>;
|
||||
};
|
||||
|
||||
&panel {
|
||||
compatible = "sharp,ls055d1sx04";
|
||||
|
||||
dvdd-supply = <&disp_dvdd_vreg>;
|
||||
ports {
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
panel_in1: endpoint {
|
||||
remote-endpoint = <&dsi1_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pm8005_gpio {
|
||||
ear_en_default: ear-en-active {
|
||||
pins = "gpio1";
|
||||
function = "normal";
|
||||
bias-disable;
|
||||
drive-push-pull;
|
||||
output-high;
|
||||
power-source = <1>; /* 1.8V */
|
||||
qcom,drive-strength = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
&pmi8998_gpio {
|
||||
disp_dvdd_en: disp-dvdd-en-active {
|
||||
pins = "gpio10";
|
||||
|
|
@ -53,3 +101,17 @@
|
|||
regulator-min-microvolt = <2704000>;
|
||||
regulator-max-microvolt = <2704000>;
|
||||
};
|
||||
|
||||
|
||||
&pmi8998_wled {
|
||||
status = "okay";
|
||||
|
||||
//qcom,auto-string-detection;
|
||||
qcom,num-strings = <3>;
|
||||
qcom,enabled-strings = <0 1 2>;
|
||||
};
|
||||
|
||||
&wcd9335 {
|
||||
pinctrl-0 = <&cdc_reset_n &wcd_int_n &ear_en_default>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@
|
|||
qcom,soft-start-us = <800>;
|
||||
};
|
||||
|
||||
&wcd9335 {
|
||||
pinctrl-0 = <&cdc_reset_n &wcd_int_n>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
&vreg_l18a_2p85 {
|
||||
regulator-min-microvolt = <2850000>;
|
||||
regulator-max-microvolt = <2850000>;
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@
|
|||
qcom,msm-id = <0x124 0x20000>, <0x124 0x20001>; /* 8998v2, v2.1 */
|
||||
qcom,board-id = <8 0>;
|
||||
|
||||
clocks {
|
||||
compatible = "simple-bus";
|
||||
chosen {
|
||||
bootargs = "clk_ignore_unused root=/dev/mmcblk0p1";
|
||||
};
|
||||
|
||||
clocks {
|
||||
div1_mclk: divclk1 {
|
||||
compatible = "gpio-gate-clock";
|
||||
pinctrl-0 = <&audio_mclk_pin>;
|
||||
|
|
@ -84,6 +86,15 @@
|
|||
pinctrl-0 = <&ts_vddio_en>;
|
||||
};
|
||||
|
||||
/* The gpio-vibrator driver enforces requiring a regulator */
|
||||
vib_vreg: vib-regulator {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vib";
|
||||
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
vph_pwr: vph-pwr-regulator {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vph_pwr";
|
||||
|
|
@ -91,6 +102,14 @@
|
|||
regulator-boot-on;
|
||||
};
|
||||
|
||||
extcon_usb: extcon-usb {
|
||||
compatible = "linux,extcon-usb-gpio";
|
||||
id-gpio = <&tlmm 38 GPIO_ACTIVE_HIGH>;
|
||||
vbus-gpio = <&tlmm 128 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&usb_extcon_active &usb_vbus_active>;
|
||||
};
|
||||
|
||||
gpio-keys {
|
||||
compatible = "gpio-keys";
|
||||
label = "Side buttons";
|
||||
|
|
@ -184,11 +203,28 @@
|
|||
vibrator {
|
||||
compatible = "gpio-vibrator";
|
||||
enable-gpios = <&pmi8998_gpio 5 GPIO_ACTIVE_HIGH>;
|
||||
vcc-supply = <&vib_vreg>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&vib_default>;
|
||||
};
|
||||
};
|
||||
|
||||
&adreno_gpu {
|
||||
status = "ok";
|
||||
|
||||
zap-shader {
|
||||
memory-region = <&zap_shader_region>;
|
||||
};
|
||||
};
|
||||
|
||||
&adreno_smmu {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&apc_cprh {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&blsp1_i2c5 {
|
||||
status = "okay";
|
||||
clock-frequency = <355000>;
|
||||
|
|
@ -241,10 +277,79 @@
|
|||
};
|
||||
};
|
||||
|
||||
&blsp2_i2c1 {
|
||||
tof-sensor@29 {
|
||||
compatible = "st,vl53l0x";
|
||||
reg = <0x29>;
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
|
||||
#io-channel-cells = <1>;
|
||||
label = "back_camera_tof";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&tof_int_n &tof_rst_n>;
|
||||
};
|
||||
};
|
||||
|
||||
&blsp2_uart1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cpufreq_hw {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&dsi0 {
|
||||
status = "okay";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
vdd-supply = <&vreg_l1a_0p875>;
|
||||
vdda-supply = <&vreg_l2a_1p2>;
|
||||
|
||||
panel: panel@0 {
|
||||
reg = <0>;
|
||||
|
||||
backlight = <&pmi8998_wled>;
|
||||
disp-te-gpios = <&tlmm 10 GPIO_ACTIVE_HIGH>;
|
||||
reset-gpios = <&tlmm 94 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
avdd-supply = <&lab>;
|
||||
avee-supply = <&ibb>;
|
||||
vddio-supply = <&vreg_l14a_1p85>;
|
||||
tavdd-supply = <&vreg_l28_3p0>;
|
||||
tvddio-supply = <&touch_vddio_vreg>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&panel_reset_n &mdp_vsync_n>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
panel_in0: endpoint {
|
||||
remote-endpoint = <&dsi0_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&dsi0_out {
|
||||
remote-endpoint = <&panel_in0>;
|
||||
data-lanes = <0 1 2 3>;
|
||||
};
|
||||
|
||||
&dsi0_phy {
|
||||
status = "okay";
|
||||
vdds-supply = <&vreg_l1a_0p875>;
|
||||
};
|
||||
|
||||
&gpucc {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&ibb {
|
||||
regulator-min-microamp = <800000>;
|
||||
regulator-max-microamp = <800000>;
|
||||
|
|
@ -270,6 +375,13 @@
|
|||
regulator-soft-start;
|
||||
};
|
||||
|
||||
&lpass_q6_smmu {
|
||||
qcom,bypass-cbndx = /bits/ 8 <11>;
|
||||
qcom,reset-nodisable-cbs = /bits/ 8 <12>;
|
||||
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
&mmcc {
|
||||
status = "ok";
|
||||
};
|
||||
|
|
@ -278,19 +390,23 @@
|
|||
status = "ok";
|
||||
};
|
||||
|
||||
&pm8005_lsid1 {
|
||||
pm8005-regulators {
|
||||
compatible = "qcom,pm8005-regulators";
|
||||
&mdss {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
vdd_s1-supply = <&vph_pwr>;
|
||||
|
||||
/* VDD_GFX supply */
|
||||
pm8005_s1: s1 {
|
||||
regulator-min-microvolt = <524000>;
|
||||
regulator-max-microvolt = <1088000>;
|
||||
regulator-enable-ramp-delay = <500>;
|
||||
regulator-always-on;
|
||||
};
|
||||
&pm8005_regulators {
|
||||
/* VDD_GFX supply */
|
||||
pm8005_s1: s1 {
|
||||
/*
|
||||
* HACK: Set enough voltage for max GPU frequency
|
||||
* and set the regulator always on until the
|
||||
* GPU Core Power Reduction gets available
|
||||
*/
|
||||
regulator-min-microvolt = <988000>;
|
||||
regulator-max-microvolt = <1088000>;
|
||||
regulator-enable-ramp-delay = <500>;
|
||||
/* Hack until we rig up the gpu consumer */
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -324,6 +440,13 @@
|
|||
function = "func2";
|
||||
power-source = <0>;
|
||||
};
|
||||
|
||||
nfc_clk_req_pin: nfc-clk-req-active {
|
||||
pins = "gpio21";
|
||||
function = PMIC_GPIO_FUNC_NORMAL;
|
||||
input-enable;
|
||||
power-source = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
&pmi8998_gpio {
|
||||
|
|
@ -358,6 +481,37 @@
|
|||
};
|
||||
};
|
||||
|
||||
&pmi8998_wled {
|
||||
status = "okay";
|
||||
|
||||
default-brightness = <800>;
|
||||
qcom,switching-freq = <800>;
|
||||
qcom,ovp-millivolt = <29600>;
|
||||
qcom,current-boost-limit = <970>;
|
||||
qcom,current-limit-microamp = <25000>;
|
||||
qcom,num-strings = <2>;
|
||||
qcom,enabled-strings = <0 1>;
|
||||
};
|
||||
|
||||
&q6asmdai {
|
||||
dai@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
dai@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
|
||||
dai@2 {
|
||||
reg = <2>;
|
||||
};
|
||||
dai@3 {
|
||||
reg = <3>;
|
||||
// direction = <2>;
|
||||
// is-compress-dai;
|
||||
};
|
||||
};
|
||||
|
||||
&qusb2phy {
|
||||
status = "okay";
|
||||
|
||||
|
|
@ -365,6 +519,19 @@
|
|||
vdda-phy-dpdm-supply = <&vreg_l24a_3p075>;
|
||||
};
|
||||
|
||||
&remoteproc_adsp {
|
||||
firmware-name = "adsp.mdt";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&remoteproc_mss {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&remoteproc_slpi {
|
||||
firmware-name = "slpi.mdt";
|
||||
};
|
||||
|
||||
&rpm_requests {
|
||||
pm8998-regulators {
|
||||
compatible = "qcom,rpm-pm8998-regulators";
|
||||
|
|
@ -401,131 +568,162 @@
|
|||
regulator-min-microvolt = <1352000>;
|
||||
regulator-max-microvolt = <1352000>;
|
||||
};
|
||||
|
||||
vreg_s4a_1p8: s4 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-system-load = <100000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_s5a_2p04: s5 {
|
||||
regulator-min-microvolt = <1904000>;
|
||||
regulator-max-microvolt = <2032000>;
|
||||
};
|
||||
|
||||
vreg_s7a_1p025: s7 {
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1028000>;
|
||||
};
|
||||
|
||||
vreg_l1a_0p875: l1 {
|
||||
regulator-min-microvolt = <880000>;
|
||||
regulator-max-microvolt = <880000>;
|
||||
regulator-system-load = <73400>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l2a_1p2: l2 {
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
regulator-system-load = <12560>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l3a_1p0: l3 {
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <1000000>;
|
||||
};
|
||||
|
||||
vreg_l5a_0p8: l5 {
|
||||
regulator-min-microvolt = <800000>;
|
||||
regulator-max-microvolt = <800000>;
|
||||
};
|
||||
|
||||
vreg_l6a_1p8: l6 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
vreg_l7a_1p8: l7 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
vreg_l8a_1p2: l8 {
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
};
|
||||
|
||||
vreg_l9a_1p8: l9 {
|
||||
regulator-min-microvolt = <1808000>;
|
||||
regulator-max-microvolt = <2960000>;
|
||||
};
|
||||
|
||||
vreg_l10a_1p8: l10 {
|
||||
regulator-min-microvolt = <1808000>;
|
||||
regulator-max-microvolt = <2960000>;
|
||||
};
|
||||
|
||||
vreg_l11a_1p0: l11 {
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <1000000>;
|
||||
};
|
||||
|
||||
vreg_l12a_1p8: l12 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
vreg_l13a_2p95: l13 {
|
||||
regulator-min-microvolt = <1808000>;
|
||||
regulator-max-microvolt = <2960000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l14a_1p85: l14 {
|
||||
regulator-min-microvolt = <1848000>;
|
||||
regulator-max-microvolt = <1856000>;
|
||||
regulator-system-load = <32000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l15a_1p8: l15 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
vreg_l16a_2p7: l16 {
|
||||
regulator-min-microvolt = <2704000>;
|
||||
regulator-max-microvolt = <2704000>;
|
||||
};
|
||||
|
||||
vreg_l17a_1p3: l17 {
|
||||
regulator-min-microvolt = <1304000>;
|
||||
regulator-max-microvolt = <1304000>;
|
||||
};
|
||||
vreg_l18a_2p85: l18 {};
|
||||
|
||||
vreg_l18a_2p85: l18 { };
|
||||
|
||||
vreg_l19a_2p7: l19 {
|
||||
regulator-min-microvolt = <2696000>;
|
||||
regulator-max-microvolt = <2704000>;
|
||||
};
|
||||
|
||||
vreg_l20a_2p95: l20 {
|
||||
regulator-min-microvolt = <2960000>;
|
||||
regulator-max-microvolt = <2960000>;
|
||||
regulator-system-load = <10000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l21a_2p95: l21 {
|
||||
regulator-min-microvolt = <2960000>;
|
||||
regulator-max-microvolt = <2960000>;
|
||||
regulator-system-load = <800000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l22a_2p85: l22 { };
|
||||
|
||||
vreg_l23a_3p3: l23 {
|
||||
regulator-min-microvolt = <3312000>;
|
||||
regulator-max-microvolt = <3312000>;
|
||||
};
|
||||
|
||||
vreg_l24a_3p075: l24 {
|
||||
regulator-min-microvolt = <3088000>;
|
||||
regulator-max-microvolt = <3088000>;
|
||||
};
|
||||
|
||||
vreg_l25a_3p3: l25 {
|
||||
regulator-min-microvolt = <3104000>;
|
||||
regulator-max-microvolt = <3312000>;
|
||||
};
|
||||
|
||||
vreg_l26a_1p2: l26 {
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
regulator-allow-set-load;
|
||||
};
|
||||
|
||||
vreg_l28_3p0: l28 {
|
||||
regulator-min-microvolt = <3000000>;
|
||||
regulator-max-microvolt = <3000000>;
|
||||
};
|
||||
|
||||
vreg_lvs1a_1p8: lvs1 { };
|
||||
|
||||
vreg_lvs2a_1p8: lvs2 { };
|
||||
};
|
||||
|
||||
|
|
@ -549,8 +747,373 @@
|
|||
vqmmc-supply = <&vreg_l13a_2p95>;
|
||||
|
||||
pinctrl-names = "default", "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>;
|
||||
pinctrl-0 = <&sdc2_on &sdc2_cd>;
|
||||
pinctrl-1 = <&sdc2_off &sdc2_cd>;
|
||||
};
|
||||
|
||||
/* EAR-EN is NXP NX5L2750C */
|
||||
|
||||
/* Downstream example
|
||||
&snd_9335 {
|
||||
qcom,msm-mbhc-hphl-swh = <1>;
|
||||
/delete-property/ qcom,hph-en1-gpio;
|
||||
/delete-property/ qcom,hph-en0-gpio;
|
||||
/delete-property/ qcom,us-euro-gpios;
|
||||
qcom,ear-en-gpios = <&pm8005_gpios 1 0>;
|
||||
qcom,audio-routing =
|
||||
"AIF4 VI", "MCLK",
|
||||
"RX_BIAS", "MCLK",
|
||||
"MADINPUT", "MCLK",
|
||||
"AMIC2", "MIC BIAS2",
|
||||
"MIC BIAS2", "Headset Mic",
|
||||
"MIC BIAS2", "ANCRight Headset Mic",
|
||||
"AMIC3", "MIC BIAS3",
|
||||
"MIC BIAS3", "ANCLeft Headset Mic",
|
||||
"DMIC0", "MIC BIAS1",
|
||||
"MIC BIAS1", "Digital Mic0",
|
||||
"DMIC3", "MIC BIAS4",
|
||||
"MIC BIAS4", "Digital Mic3",
|
||||
"SpkrLeft IN", "SPK1 OUT",
|
||||
"SpkrRight IN", "SPK2 OUT";
|
||||
};
|
||||
*/
|
||||
|
||||
&slimbam {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&slim {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&slim_ngd {
|
||||
tasha_ifd: tas-ifd {
|
||||
compatible = "slim217,1a0";
|
||||
reg = <0 0>;
|
||||
};
|
||||
|
||||
wcd9335: codec@1{
|
||||
compatible = "slim217,1a0";
|
||||
reg = <1 0>;
|
||||
|
||||
clock-names = "mclk", "slimbus";
|
||||
clocks = <&div1_mclk>,
|
||||
<&rpmcc RPM_SMD_LN_BB_CLK1>;
|
||||
#clock-cells = <0>;
|
||||
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <54 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<53 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "intr1", "intr2";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
slim-ifc-dev = <&tasha_ifd>;
|
||||
|
||||
vdd-buck-supply = <&vreg_s4a_1p8>;
|
||||
vdd-buck-sido-supply = <&vreg_s4a_1p8>;
|
||||
vdd-tx-supply = <&vreg_s4a_1p8>;
|
||||
vdd-rx-supply = <&vreg_s4a_1p8>;
|
||||
vdd-io-supply = <&vreg_s4a_1p8>;
|
||||
qcom,mbhc-vthreshold = <1700>;
|
||||
|
||||
/* On SoMC Yoshino, HPHL is normally open, GND normally closed */
|
||||
qcom,hphl-jack-type-normally-open;
|
||||
//qcom,gnd-jack-type-normally-open;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
#sound-dai-cells = <1>;
|
||||
|
||||
swm: swm@c85 {
|
||||
compatible = "qcom,soundwire-v1.3.0";
|
||||
reg = <0xc85 0x40>;
|
||||
interrupts-extended = <&wcd9335 13>;
|
||||
|
||||
qcom,dout-ports = <6>;
|
||||
qcom,din-ports = <2>;
|
||||
qcom,ports-sinterval-low =/bits/ 8 <0x07 0x1F 0x3F 0x7 0x1F 0x3F 0x0F 0x0F>;
|
||||
qcom,ports-offset1 = /bits/ 8 <0x01 0x02 0x0C 0x6 0x12 0x0D 0x07 0x0A >;
|
||||
qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x1F 0x00 0x00 0x1F 0x00 0x00>;
|
||||
/*downstream is <0xFF 0x00 0x1F 0xFF 0x00 0x1F 0x00 0x00>;*/
|
||||
qcom,ports-block-pack-mode = /bits/ 8 <0xFF 0xFF 0x01 0xFF 0xFF 0x01 0xFF 0xFF>;
|
||||
clocks = <&xo>;
|
||||
clock-names = "iface";
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
#sound-dai-cells = <1>;
|
||||
|
||||
left_spkr: wsa8810-left {
|
||||
compatible = "sdw10217201000";
|
||||
reg = <0 1>;
|
||||
powerdown-gpios = <&tlmm 65 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-0 = <&wsa_leftspk_pwr_n>;
|
||||
pinctrl-names = "default";
|
||||
#thermal-sensor-cells = <0>;
|
||||
sound-name-prefix = "SpkrRight";
|
||||
#sound-dai-cells = <0>;
|
||||
};
|
||||
|
||||
right_spkr: wsa8810-right {
|
||||
compatible = "sdw10217201000";
|
||||
powerdown-gpios = <&tlmm 66 GPIO_ACTIVE_HIGH>;
|
||||
reg = <0 2>;
|
||||
pinctrl-0 = <&wsa_rightspk_pwr_n>;
|
||||
pinctrl-names = "default";
|
||||
#thermal-sensor-cells = <0>;
|
||||
sound-name-prefix = "SpkrLeft";
|
||||
#sound-dai-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/* NOTES */
|
||||
/*
|
||||
# This is Dragonboard 820C
|
||||
EnableSequence [
|
||||
cset "name='SLIM RX0 MUX' ZERO"
|
||||
cset "name='SLIM RX1 MUX' ZERO"
|
||||
cset "name='SLIM RX2 MUX' ZERO"
|
||||
cset "name='SLIM RX3 MUX' ZERO"
|
||||
cset "name='SLIM RX4 MUX' ZERO"
|
||||
cset "name='SLIM RX5 MUX' AIF4_PB"
|
||||
cset "name='SLIM RX6 MUX' AIF4_PB"
|
||||
cset "name='SLIM RX7 MUX' ZERO"
|
||||
cset "name='RX INT1_2 MUX' RX5"
|
||||
cset "name='RX INT2_2 MUX' RX6"
|
||||
## gain to 0dB
|
||||
cset "name='RX5 Digital Volume' 68"
|
||||
## gain to 0dB
|
||||
cset "name='RX6 Digital Volume' 68"
|
||||
cset "name='SLIMBUS_6_RX Audio Mixer MultiMedia2' 1"
|
||||
cset "name='RX INT1 DEM MUX' CLSH_DSM_OUT"
|
||||
cset "name='RX INT2 DEM MUX' CLSH_DSM_OUT"
|
||||
]
|
||||
|
||||
|
||||
######### WORKS!!!!!! SHE SPEEEEEAKS!!!!!!! #########
|
||||
tinymix set "SLIM RX2 MUX" ZERO
|
||||
tinymix set "SLIM RX3 MUX" ZERO
|
||||
tinymix set "SLIM RX4 MUX" ZERO
|
||||
tinymix set "SLIM RX5 MUX" ZERO
|
||||
tinymix set "SLIM RX6 MUX" ZERO
|
||||
tinymix set "SLIM RX7 MUX" ZERO
|
||||
tinymix set "SLIM RX0 MUX" AIF1_PB
|
||||
tinymix set "SLIM RX1 MUX" AIF1_PB
|
||||
tinymix set "RX INT1_2 MUX" RX0
|
||||
tinymix set "RX INT2_2 MUX" RX1
|
||||
tinymix set "RX INT1_1 MIX1 INP0" RX0
|
||||
tinymix set "RX INT2_1 MIX1 INP0" RX1
|
||||
tinymix set "SLIMBUS_0_RX Audio Mixer MultiMedia1" 1
|
||||
tinymix set "RX INT1 DEM MUX" CLSH_DSM_OUT
|
||||
tinymix set "RX INT2 DEM MUX" CLSH_DSM_OUT
|
||||
tinymix set "SLIM TX0 MUX" DEC0
|
||||
tinymix set "AIF1_CAP Mixer SLIM TX0" 1
|
||||
|
||||
tinymix set "RX INT2_1 MIX1 INP0" RX1
|
||||
tinymix set "RX INT1_1 MIX1 INP0" RX0
|
||||
tinymix set "RX INT1_1 MIX1 INP0" RX2
|
||||
tinymix set "RX INT1_1 MIX1 INP0" RX0
|
||||
tinymix set "RX INT1_1 MIX1 INP0" RX2
|
||||
tinymix set "RX INT2_1 MIX1 INP0" RX2
|
||||
tinymix set "RX INT2_1 MIX1 INP0" RX1
|
||||
tinymix set "RX INT1_1 MIX1 INP0" RX0
|
||||
tinymix set "RX INT0_1 MIX1 INP0" RX0
|
||||
tinymix set "RX INT0_1 MIX1 INP0" RX1
|
||||
tinymix set "RX INT0_1 MIX1 INP0" RX2
|
||||
tinymix set "RX INT0_1 MIX1 INP0" RX0
|
||||
tinymix set "RX INT3_1 MIX1 INP0" RX0
|
||||
tinymix set "RX INT4_1 MIX1 INP0" RX0
|
||||
tinymix set "RX INT5_1 MIX1 INP0" RX0
|
||||
tinymix set "RX INT6_1 MIX1 INP0" RX1
|
||||
tinymix set "RX INT7_1 MIX1 INP0" RX1
|
||||
tinymix set "RX INT7_1 MIX1 INP0" RX1
|
||||
tinymix set "RX INT8_1 MIX1 INP0" RX1
|
||||
tinymix set "RX INT0_1 MIX1 INP1" RX0
|
||||
tinymix set "RX INT0_1 MIX1 INP1" RX2
|
||||
tinymix set "RX INT0_1 MIX1 INP1" RX0
|
||||
tinymix set "RX INT1_1 MIX1 INP1" RX0
|
||||
tinymix set "RX INT2_1 MIX1 INP1" RX0
|
||||
tinymix set "RX INT3_1 MIX1 INP1" RX0
|
||||
tinymix set "RX INT4_1 MIX1 INP1" RX0
|
||||
tinymix set "RX INT5_1 MIX1 INP1" RX0
|
||||
tinymix set "RX INT6_1 MIX1 INP1" RX0
|
||||
tinymix set "RX INT7_1 MIX1 INP1" RX0
|
||||
tinymix set "RX INT8_1 MIX1 INP1" RX0
|
||||
tinymix set "RX INT0_1 MIX1 INP2" RX1
|
||||
tinymix set "RX INT1_1 MIX1 INP2" RX1
|
||||
tinymix set "RX INT2_1 MIX1 INP2" RX1
|
||||
tinymix set "RX INT3_1 MIX1 INP2" RX1
|
||||
tinymix set "RX INT4_1 MIX1 INP2" RX1
|
||||
tinymix set "RX INT5_1 MIX1 INP2" RX1
|
||||
tinymix set "RX INT6_1 MIX1 INP2" RX1
|
||||
tinymix set "RX INT7_1 MIX1 INP2" RX1
|
||||
tinymix set "RX INT8_1 MIX1 INP2" RX1
|
||||
tinymix set "RX INT8_1 MIX1 INP2" RX0
|
||||
tinymix set "RX INT7_1 MIX1 INP2" RX0
|
||||
tinymix set "RX INT6_1 MIX1 INP2" RX0
|
||||
|
||||
tinymix set "RX0 Digital Volume" 80
|
||||
tinymix set "RX1 Digital Volume" 80
|
||||
tinymix set "RX2 Digital Volume" 80
|
||||
|
||||
*/
|
||||
|
||||
&sound {
|
||||
compatible = "qcom,msm8998-sndcard";
|
||||
model = "Sony-Xperia-Yoshino";
|
||||
|
||||
/* Audio routing including WSA amp speakers */
|
||||
/* audio-routing = "RX_BIAS", "MCLK",
|
||||
"AMIC2", "MIC BIAS2",
|
||||
"AMIC3", "MIC BIAS3",
|
||||
"DMIC0", "MIC BIAS1",
|
||||
"DMIC4", "MIC BIAS4",
|
||||
"SpkrLeft IN", "SPK1 OUT",
|
||||
"SpkrRight IN", "SPK2 OUT",
|
||||
"MM_DL1", "MultiMedia1 Playback",
|
||||
"MM_DL2", "MultiMedia2 Playback",
|
||||
"MultiMedia3 Capture", "MM_UL3";
|
||||
*/
|
||||
|
||||
/* Basic routing, 3.5mm jack only */
|
||||
audio-routing = "RX_BIAS", "MCLK",
|
||||
"AMIC2", "MIC BIAS2",
|
||||
"AMIC3", "MIC BIAS3",
|
||||
"DMIC0", "MIC BIAS1",
|
||||
"DMIC4", "MIC BIAS4",
|
||||
"MM_DL1", "MultiMedia1 Playback",
|
||||
"MM_DL2", "MultiMedia2 Playback",
|
||||
"MultiMedia3 Capture", "MM_UL3";
|
||||
|
||||
/*
|
||||
<path name="voicemmode1-call headphones">
|
||||
<ctl name="SLIM_0_RX_Voice Mixer VoiceMMode1" value="1" />
|
||||
<ctl name="VoiceMMode1_Tx Mixer SLIM_0_TX_MMode1" value="1" />
|
||||
</path>
|
||||
|
||||
<path name="sidetone-headphones">
|
||||
<path name="sidetone-iir" />
|
||||
<!-- 45 % of 124 (range 0 - 124) Register: 0x340 -->
|
||||
<ctl name="IIR0 INP0 Volume" value="44" />
|
||||
<ctl name="RX INT1 MIX2 INP" value="SRC0" />
|
||||
<ctl name="RX INT2 MIX2 INP" value="SRC0" />
|
||||
</path>
|
||||
|
||||
<path name="speaker-and-headphones">
|
||||
<path name="speaker" />
|
||||
<ctl name="RX INT1_1 MIX1 INP0" value="RX1" />
|
||||
<ctl name="RX INT2_1 MIX1 INP0" value="RX1" />
|
||||
<ctl name="RX INT1 DEM MUX" value="CLSH_DSM_OUT" />
|
||||
<ctl name="RX INT2 DEM MUX" value="CLSH_DSM_OUT" />
|
||||
<ctl name="RX1 Digital Volume" value="55" />
|
||||
<ctl name="RX2 Digital Volume" value="55" />
|
||||
<path name="headphones-hpf" />
|
||||
<ctl name="Set Custom Stereo" value="Mix" />
|
||||
</path>
|
||||
|
||||
<path name="headphones">
|
||||
<ctl name="SLIM RX0 MUX" value="AIF_MIX1_PB" />
|
||||
<ctl name="SLIM RX1 MUX" value="AIF_MIX1_PB" />
|
||||
<ctl name="SLIM_0_RX Channels" value="Two" />
|
||||
<ctl name="RX INT1_1 MIX1 INP0" value="RX0" />
|
||||
<ctl name="RX INT2_1 MIX1 INP0" value="RX1" />
|
||||
<ctl name="RX INT1 DEM MUX" value="CLSH_DSM_OUT" />
|
||||
<ctl name="RX INT2 DEM MUX" value="CLSH_DSM_OUT" />
|
||||
<ctl name="RX1 Digital Volume" value="80" />
|
||||
<ctl name="RX2 Digital Volume" value="80" />
|
||||
</path>
|
||||
|
||||
<path name="headphones-hpf">
|
||||
<ctl name="RX INT1_1 HPF cut off" value="CF_NEG_3DB_150HZ" />
|
||||
<ctl name="RX INT2_1 HPF cut off" value="CF_NEG_3DB_150HZ" />
|
||||
</path>
|
||||
|
||||
|
||||
<path name="anc-off-headphone">
|
||||
<ctl name="SLIM RX0 MUX" value="AIF_MIX1_PB" />
|
||||
<ctl name="SLIM RX1 MUX" value="AIF_MIX1_PB" />
|
||||
<ctl name="SLIM_0_RX Channels" value="Two" />
|
||||
<ctl name="RX INT1_1 MIX1 INP0" value="RX0" />
|
||||
<ctl name="RX INT2_1 MIX1 INP0" value="RX1" />
|
||||
<ctl name="RX INT1 DEM MUX" value="CLSH_DSM_OUT" />
|
||||
<ctl name="RX INT2 DEM MUX" value="CLSH_DSM_OUT" />
|
||||
<ctl name="COMP1 Switch" value="0" />
|
||||
<ctl name="COMP2 Switch" value="0" />
|
||||
<ctl name="HPHL Volume" value="20" />
|
||||
<ctl name="HPHR Volume" value="20" />
|
||||
<ctl name="RX1 Digital Volume" value="77" />
|
||||
<ctl name="RX2 Digital Volume" value="77" />
|
||||
</path>
|
||||
|
||||
<path name="audio-record">
|
||||
<ctl name="MultiMedia1 Mixer SLIM_0_TX" value="1" />
|
||||
</path>
|
||||
|
||||
<path name="deep-buffer-playback">
|
||||
<ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia1" value="1" />
|
||||
</path>
|
||||
*/
|
||||
|
||||
mm1-dai-link {
|
||||
/* Deep Buffer playback for SLIM{0,7}, BT, USBAUDIO, AFE, DP, HDMI */
|
||||
link-name = "MultiMedia1";
|
||||
cpu {
|
||||
sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>;
|
||||
};
|
||||
};
|
||||
|
||||
mm2-dai-link {
|
||||
/* Multichannel playback for HDMI and DP */
|
||||
link-name = "MultiMedia2";
|
||||
cpu {
|
||||
sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA2>;
|
||||
};
|
||||
};
|
||||
|
||||
mm3-dai-link {
|
||||
/* Ultra Low Latency playback for SLIM0, HDMI, and DP */
|
||||
link-name = "MultiMedia3";
|
||||
cpu {
|
||||
sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA3>;
|
||||
};
|
||||
};
|
||||
|
||||
slim-dai-link {
|
||||
link-name = "SLIM Playback";
|
||||
cpu {
|
||||
sound-dai = <&q6afedai SLIMBUS_0_RX>;
|
||||
};
|
||||
|
||||
platform {
|
||||
sound-dai = <&q6routing>;
|
||||
};
|
||||
|
||||
codec {
|
||||
/* Support only sound through 3.5mm for now: soundwire is currently unavailable */
|
||||
//sound-dai = <&left_spkr>, <&right_spkr>, <&swm 0>, <&wcd9335 0>;
|
||||
sound-dai = <&wcd9335 0>;
|
||||
};
|
||||
};
|
||||
|
||||
slimcap-dai-link {
|
||||
link-name = "SLIM Capture";
|
||||
cpu {
|
||||
sound-dai = <&q6afedai SLIMBUS_0_TX>;
|
||||
};
|
||||
|
||||
platform {
|
||||
sound-dai = <&q6routing>;
|
||||
};
|
||||
|
||||
codec {
|
||||
sound-dai = <&wcd9335 1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
|
|
@ -606,6 +1169,14 @@
|
|||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
tof_int_n: tof-int-n {
|
||||
pins = "gpio22";
|
||||
function = "gpio";
|
||||
bias-pull-up;
|
||||
drive-strength = <2>;
|
||||
input-enable;
|
||||
};
|
||||
|
||||
cam1_vdig_default: cam1-vdig-default {
|
||||
pins = "gpio25";
|
||||
function = "gpio";
|
||||
|
|
@ -613,6 +1184,81 @@
|
|||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
tof_rst_n: tof-rst-n {
|
||||
pins = "gpio27";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
output-low;
|
||||
};
|
||||
|
||||
cam1_rst_default: cam1-rst-n {
|
||||
pins = "gpio28";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
cam0_rst_default: cam0-rst-n {
|
||||
pins = "gpio30";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
wcd_int_n: wcd-int-n {
|
||||
pins = "gpio54";
|
||||
function = "gpio";
|
||||
bias-pull-down;
|
||||
drive-strength = <2>;
|
||||
input-enable;
|
||||
};
|
||||
|
||||
cdc_reset_n: cdc-reset-n {
|
||||
pins = "gpio64";
|
||||
function = "gpio";
|
||||
bias-pull-down;
|
||||
drive-strength = <16>;
|
||||
output-high;
|
||||
};
|
||||
|
||||
wsa_leftspk_pwr_n: wsa-leftspk-pwr-n {
|
||||
pins = "gpio65";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
output-low;
|
||||
};
|
||||
|
||||
wsa_rightspk_pwr_n: wsa-rightspk-pwr-n {
|
||||
pins = "gpio66";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
output-low;
|
||||
};
|
||||
|
||||
ts_reset_n: ts-reset-n {
|
||||
pins = "gpio89";
|
||||
function = "gpio";
|
||||
bias-pull-up;
|
||||
drive-strength = <8>;
|
||||
};
|
||||
|
||||
panel_reset_n: panel-rst-n {
|
||||
pins = "gpio94";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
};
|
||||
|
||||
usb_extcon_active: usb-extcon-active {
|
||||
pins = "gpio38";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <16>;
|
||||
};
|
||||
|
||||
hall_sensor0_default: acc-cover-open {
|
||||
pins = "gpio124";
|
||||
function = "gpio";
|
||||
|
|
@ -628,6 +1274,14 @@
|
|||
bias-pull-up;
|
||||
};
|
||||
|
||||
usb_vbus_active: usb-vbus-active {
|
||||
pins = "gpio128";
|
||||
function = "gpio";
|
||||
bias-disable;
|
||||
drive-strength = <2>;
|
||||
output-low;
|
||||
};
|
||||
|
||||
ts_vddio_en: ts-vddio-en-default {
|
||||
pins = "gpio133";
|
||||
function = "gpio";
|
||||
|
|
@ -658,6 +1312,7 @@
|
|||
&usb3_dwc3 {
|
||||
/* Force to peripheral until we have Type-C hooked up */
|
||||
dr_mode = "peripheral";
|
||||
extcon = <&extcon_usb>;
|
||||
};
|
||||
|
||||
&usb3phy {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -28,5 +28,9 @@
|
|||
reg = <0x5 SPMI_USID>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pm8005_regulators: regulators {
|
||||
compatible = "qcom,pm8005-regulators";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -78,6 +78,16 @@
|
|||
#size-cells = <0>;
|
||||
#io-channel-cells = <1>;
|
||||
|
||||
adc-chan@0 {
|
||||
reg = <ADC5_REF_GND>;
|
||||
label = "ref_gnd";
|
||||
};
|
||||
|
||||
adc-chan@1 {
|
||||
reg = <ADC5_REF_GND>;
|
||||
label = "vref_1p25";
|
||||
};
|
||||
|
||||
adc-chan@6 {
|
||||
reg = <ADC5_DIE_TEMP>;
|
||||
label = "die_temp";
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <dt-bindings/input/qcom,spmi-haptics.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/spmi/spmi.h>
|
||||
|
||||
|
|
@ -9,6 +10,23 @@
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pmi8998_charger: charger@1000 {
|
||||
compatible = "qcom,pmi8998-charger";
|
||||
reg = <0x1000>;
|
||||
|
||||
interrupts = <0x2 0x13 0x4 IRQ_TYPE_EDGE_BOTH>,
|
||||
<0x2 0x12 0x2 IRQ_TYPE_EDGE_BOTH>,
|
||||
<0x2 0x16 0x1 IRQ_TYPE_EDGE_RISING>,
|
||||
<0x2 0x13 0x6 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "usb-plugin", "bat-ov", "wdog-bark", "usbin-icl-change";
|
||||
|
||||
io-channels = <&pmi8998_rradc 3>,
|
||||
<&pmi8998_rradc 4>;
|
||||
io-channel-names = "usbin_i", "usbin_v";
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pmi8998_gpio: gpios@c000 {
|
||||
compatible = "qcom,pmi8998-gpio", "qcom,spmi-gpio";
|
||||
reg = <0xc000>;
|
||||
|
|
@ -18,6 +36,14 @@
|
|||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
pmi8998_rradc: rradc@4500 {
|
||||
compatible = "qcom,pmi8998-rradc";
|
||||
reg = <0x4500>;
|
||||
#io-channel-cells = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
pmi8998_lsid1: pmic@3 {
|
||||
|
|
@ -53,5 +79,29 @@
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
pmi8998_haptics: haptics@c000 {
|
||||
compatible = "qcom,spmi-haptics";
|
||||
reg = <0xc000>;
|
||||
|
||||
interrupts = <0x3 0xc0 0x0 IRQ_TYPE_EDGE_BOTH>,
|
||||
<0x3 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>;
|
||||
interrupt-names = "short", "play";
|
||||
|
||||
qcom,wave-shape = <HAP_WAVE_SINE>;
|
||||
qcom,play-mode = <HAP_PLAY_BUFFER>;
|
||||
qcom,brake-pattern = <0x3 0x3 0x2 0x1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pmi8998_lpg: led-controller {
|
||||
compatible = "qcom,pmi8998-lpg";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#pwm-cells = <2>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1173,19 +1173,19 @@
|
|||
<&cpr_efuse_ring2>,
|
||||
<&cpr_efuse_ring3>,
|
||||
<&cpr_efuse_revision>;
|
||||
nvmem-cell-names = "cpr_quotient_offset1",
|
||||
"cpr_quotient_offset2",
|
||||
"cpr_quotient_offset3",
|
||||
"cpr_init_voltage1",
|
||||
"cpr_init_voltage2",
|
||||
"cpr_init_voltage3",
|
||||
"cpr_quotient1",
|
||||
"cpr_quotient2",
|
||||
"cpr_quotient3",
|
||||
"cpr_ring_osc1",
|
||||
"cpr_ring_osc2",
|
||||
"cpr_ring_osc3",
|
||||
"cpr_fuse_revision";
|
||||
nvmem-cell-names = "cpr0_quotient_offset1",
|
||||
"cpr0_quotient_offset2",
|
||||
"cpr0_quotient_offset3",
|
||||
"cpr0_init_voltage1",
|
||||
"cpr0_init_voltage2",
|
||||
"cpr0_init_voltage3",
|
||||
"cpr0_quotient1",
|
||||
"cpr0_quotient2",
|
||||
"cpr0_quotient3",
|
||||
"cpr0_ring_osc1",
|
||||
"cpr0_ring_osc2",
|
||||
"cpr0_ring_osc3",
|
||||
"cpr0_fuse_revision";
|
||||
};
|
||||
|
||||
timer@b120000 {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ get_cycles (void)
|
|||
ret = ia64_getreg(_IA64_REG_AR_ITC);
|
||||
return ret;
|
||||
}
|
||||
#define get_cycles get_cycles
|
||||
|
||||
extern void ia64_cpu_local_tick (void);
|
||||
extern unsigned long long ia64_native_sched_clock (void);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ static inline unsigned long random_get_entropy(void)
|
|||
{
|
||||
if (mach_random_get_entropy)
|
||||
return mach_random_get_entropy();
|
||||
return 0;
|
||||
return random_get_entropy_fallback();
|
||||
}
|
||||
#define random_get_entropy random_get_entropy
|
||||
|
||||
|
|
|
|||
|
|
@ -76,25 +76,24 @@ static inline cycles_t get_cycles(void)
|
|||
else
|
||||
return 0; /* no usable counter */
|
||||
}
|
||||
#define get_cycles get_cycles
|
||||
|
||||
/*
|
||||
* Like get_cycles - but where c0_count is not available we desperately
|
||||
* use c0_random in an attempt to get at least a little bit of entropy.
|
||||
*
|
||||
* R6000 and R6000A neither have a count register nor a random register.
|
||||
* That leaves no entropy source in the CPU itself.
|
||||
*/
|
||||
static inline unsigned long random_get_entropy(void)
|
||||
{
|
||||
unsigned int prid = read_c0_prid();
|
||||
unsigned int imp = prid & PRID_IMP_MASK;
|
||||
unsigned int c0_random;
|
||||
|
||||
if (can_use_mips_counter(prid))
|
||||
if (can_use_mips_counter(read_c0_prid()))
|
||||
return read_c0_count();
|
||||
else if (likely(imp != PRID_IMP_R6000 && imp != PRID_IMP_R6000A))
|
||||
return read_c0_random();
|
||||
|
||||
if (cpu_has_3kex)
|
||||
c0_random = (read_c0_random() >> 8) & 0x3f;
|
||||
else
|
||||
return 0; /* no usable register */
|
||||
c0_random = read_c0_random() & 0x3f;
|
||||
return (random_get_entropy_fallback() << 6) | (0x3f - c0_random);
|
||||
}
|
||||
#define random_get_entropy random_get_entropy
|
||||
|
||||
|
|
|
|||
|
|
@ -8,5 +8,8 @@
|
|||
typedef unsigned long cycles_t;
|
||||
|
||||
extern cycles_t get_cycles(void);
|
||||
#define get_cycles get_cycles
|
||||
|
||||
#define random_get_entropy() (((unsigned long)get_cycles()) ?: random_get_entropy_fallback())
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -13,9 +13,10 @@
|
|||
|
||||
typedef unsigned long cycles_t;
|
||||
|
||||
static inline cycles_t get_cycles (void)
|
||||
static inline cycles_t get_cycles(void)
|
||||
{
|
||||
return mfctl(16);
|
||||
}
|
||||
#define get_cycles get_cycles
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ static inline cycles_t get_cycles(void)
|
|||
{
|
||||
return mftb();
|
||||
}
|
||||
#define get_cycles get_cycles
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_POWERPC_TIMEX_H */
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ static inline u32 get_cycles_hi(void)
|
|||
static inline unsigned long random_get_entropy(void)
|
||||
{
|
||||
if (unlikely(clint_time_val == NULL))
|
||||
return 0;
|
||||
return random_get_entropy_fallback();
|
||||
return get_cycles();
|
||||
}
|
||||
#define random_get_entropy() random_get_entropy()
|
||||
|
|
|
|||
|
|
@ -197,6 +197,7 @@ static inline cycles_t get_cycles(void)
|
|||
{
|
||||
return (cycles_t) get_tod_clock() >> 2;
|
||||
}
|
||||
#define get_cycles get_cycles
|
||||
|
||||
int get_phys_clock(unsigned long *clock);
|
||||
void init_cpu_timer(void);
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
|
||||
|
||||
/* XXX Maybe do something better at some point... -DaveM */
|
||||
typedef unsigned long cycles_t;
|
||||
#define get_cycles() (0)
|
||||
#include <asm-generic/timex.h>
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2,13 +2,8 @@
|
|||
#ifndef __UM_TIMEX_H
|
||||
#define __UM_TIMEX_H
|
||||
|
||||
typedef unsigned long cycles_t;
|
||||
|
||||
static inline cycles_t get_cycles (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CLOCK_TICK_RATE (HZ)
|
||||
|
||||
#include <asm-generic/timex.h>
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -5,6 +5,15 @@
|
|||
#include <asm/processor.h>
|
||||
#include <asm/tsc.h>
|
||||
|
||||
static inline unsigned long random_get_entropy(void)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_X86_TSC) &&
|
||||
!cpu_feature_enabled(X86_FEATURE_TSC))
|
||||
return random_get_entropy_fallback();
|
||||
return rdtsc();
|
||||
}
|
||||
#define random_get_entropy random_get_entropy
|
||||
|
||||
/* Assume we use the PIT time source for the clock tick */
|
||||
#define CLOCK_TICK_RATE PIT_TICK_RATE
|
||||
|
||||
|
|
|
|||
|
|
@ -20,13 +20,12 @@ extern void disable_TSC(void);
|
|||
|
||||
static inline cycles_t get_cycles(void)
|
||||
{
|
||||
#ifndef CONFIG_X86_TSC
|
||||
if (!boot_cpu_has(X86_FEATURE_TSC))
|
||||
if (!IS_ENABLED(CONFIG_X86_TSC) &&
|
||||
!cpu_feature_enabled(X86_FEATURE_TSC))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return rdtsc();
|
||||
}
|
||||
#define get_cycles get_cycles
|
||||
|
||||
extern struct system_counterval_t convert_art_to_tsc(u64 art);
|
||||
extern struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns);
|
||||
|
|
|
|||
|
|
@ -29,10 +29,6 @@
|
|||
|
||||
extern unsigned long ccount_freq;
|
||||
|
||||
typedef unsigned long long cycles_t;
|
||||
|
||||
#define get_cycles() (0)
|
||||
|
||||
void local_timer_setup(unsigned cpu);
|
||||
|
||||
/*
|
||||
|
|
@ -59,4 +55,6 @@ static inline void set_linux_timer (unsigned long ccompare)
|
|||
xtensa_set_sr(ccompare, SREG_CCOMPARE + LINUX_TIMER);
|
||||
}
|
||||
|
||||
#include <asm-generic/timex.h>
|
||||
|
||||
#endif /* _XTENSA_TIMEX_H */
|
||||
|
|
|
|||
|
|
@ -415,19 +415,30 @@ static ssize_t acpi_data_show(struct file *filp, struct kobject *kobj,
|
|||
loff_t offset, size_t count)
|
||||
{
|
||||
struct acpi_data_attr *data_attr;
|
||||
void *base;
|
||||
ssize_t rc;
|
||||
void __iomem *base;
|
||||
ssize_t size;
|
||||
|
||||
data_attr = container_of(bin_attr, struct acpi_data_attr, attr);
|
||||
size = data_attr->attr.size;
|
||||
|
||||
base = acpi_os_map_memory(data_attr->addr, data_attr->attr.size);
|
||||
if (offset < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (offset >= size)
|
||||
return 0;
|
||||
|
||||
if (count > size - offset)
|
||||
count = size - offset;
|
||||
|
||||
base = acpi_os_map_iomem(data_attr->addr, size);
|
||||
if (!base)
|
||||
return -ENOMEM;
|
||||
rc = memory_read_from_buffer(buf, count, &offset, base,
|
||||
data_attr->attr.size);
|
||||
acpi_os_unmap_memory(base, data_attr->attr.size);
|
||||
|
||||
return rc;
|
||||
memcpy_fromio(buf, base + offset, count);
|
||||
|
||||
acpi_os_unmap_iomem(base, size);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int acpi_bert_data_init(void *th, struct acpi_data_attr *data_attr)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -2080,6 +2080,7 @@ static struct clk_branch gcc_bimc_gfx_clk = {
|
|||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_bimc_gfx_clk",
|
||||
.flags = CLK_IS_CRITICAL,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
|
|
@ -2220,6 +2221,7 @@ static struct clk_rcg2 hmss_gpll0_clk_src = {
|
|||
.name = "hmss_gpll0_clk_src",
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.flags = CLK_IS_CRITICAL,
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
|
@ -2833,6 +2835,43 @@ static struct clk_branch gcc_rx1_usb2_clkref_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch hlos1_vote_lpass_core_smmu_clk = {
|
||||
.halt_reg = 0x7D010,
|
||||
.clkr = {
|
||||
.enable_reg = 0x7D010,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "hlos1_vote_lpass_core_smmu_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch hlos1_vote_lpass_adsp_smmu_clk = {
|
||||
.halt_reg = 0x7D014,
|
||||
.clkr = {
|
||||
.enable_reg = 0x7D014,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "hlos1_vote_lpass_adsp_smmu_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
|
||||
.halt_reg = 0x8A040,
|
||||
.clkr = {
|
||||
.enable_reg = 0x8A040,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "gcc_mss_q6_bimc_axi_clk",
|
||||
.flags = CLK_IS_CRITICAL,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct gdsc pcie_0_gdsc = {
|
||||
.gdscr = 0x6b004,
|
||||
.gds_hw_ctrl = 0x0,
|
||||
|
|
@ -2863,6 +2902,26 @@ static struct gdsc usb_30_gdsc = {
|
|||
.flags = VOTABLE,
|
||||
};
|
||||
|
||||
static struct gdsc hlos1_vote_lpass_adsp = {
|
||||
.gdscr = 0x7d034,
|
||||
.gds_hw_ctrl = 0x0,
|
||||
.pd = {
|
||||
.name = "lpass_adsp_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = VOTABLE,
|
||||
};
|
||||
|
||||
static struct gdsc hlos1_vote_lpass_core = {
|
||||
.gdscr = 0x7d038,
|
||||
.gds_hw_ctrl = 0x0,
|
||||
.pd = {
|
||||
.name = "lpass_core_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = ALWAYS_ON,
|
||||
};
|
||||
|
||||
static struct clk_regmap *gcc_msm8998_clocks[] = {
|
||||
[BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
|
||||
[BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
|
||||
|
|
@ -3036,12 +3095,17 @@ static struct clk_regmap *gcc_msm8998_clocks[] = {
|
|||
[GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr,
|
||||
[GCC_MMSS_GPLL0_CLK] = &gcc_mmss_gpll0_clk.clkr,
|
||||
[HMSS_GPLL0_CLK_SRC] = &hmss_gpll0_clk_src.clkr,
|
||||
[GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr,
|
||||
[HLOS1_VOTE_LPASS_CORE_SMMU_CLK] = &hlos1_vote_lpass_core_smmu_clk.clkr,
|
||||
[HLOS1_VOTE_LPASS_ADSP_SMMU_CLK] = &hlos1_vote_lpass_adsp_smmu_clk.clkr,
|
||||
};
|
||||
|
||||
static struct gdsc *gcc_msm8998_gdscs[] = {
|
||||
[PCIE_0_GDSC] = &pcie_0_gdsc,
|
||||
[UFS_GDSC] = &ufs_gdsc,
|
||||
[USB_30_GDSC] = &usb_30_gdsc,
|
||||
[LPASS_ADSP_GDSC] = &hlos1_vote_lpass_adsp,
|
||||
[LPASS_CORE_GDSC] = &hlos1_vote_lpass_core,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map gcc_msm8998_resets[] = {
|
||||
|
|
@ -3191,6 +3255,14 @@ static int gcc_msm8998_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* GCC_MMSS_MISC - GCC_GPU_MISC:
|
||||
* 1. Disable the GPLL0 active input to MMSS and GPU
|
||||
* 2. Select clk division 1 (CLK/2)
|
||||
*/
|
||||
regmap_write(regmap, 0x0902C, 0x10003); /* MMSS*/
|
||||
regmap_write(regmap, 0x71028, 0x10003); /* GPU */
|
||||
|
||||
return qcom_cc_really_probe(pdev, &gcc_msm8998_desc, regmap);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -511,7 +511,7 @@ static struct clk_rcg2 byte0_clk_src = {
|
|||
.parent_data = mmss_xo_dsibyte,
|
||||
.num_parents = ARRAY_SIZE(mmss_xo_dsibyte),
|
||||
.ops = &clk_byte2_ops,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -524,7 +524,7 @@ static struct clk_rcg2 byte1_clk_src = {
|
|||
.parent_data = mmss_xo_dsibyte,
|
||||
.num_parents = ARRAY_SIZE(mmss_xo_dsibyte),
|
||||
.ops = &clk_byte2_ops,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -1075,7 +1075,7 @@ static struct clk_rcg2 pclk0_clk_src = {
|
|||
.parent_data = mmss_xo_dsi0pll_dsi1pll,
|
||||
.num_parents = ARRAY_SIZE(mmss_xo_dsi0pll_dsi1pll),
|
||||
.ops = &clk_pixel_ops,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -1089,7 +1089,7 @@ static struct clk_rcg2 pclk1_clk_src = {
|
|||
.parent_data = mmss_xo_dsi0pll_dsi1pll,
|
||||
.num_parents = ARRAY_SIZE(mmss_xo_dsi0pll_dsi1pll),
|
||||
.ops = &clk_pixel_ops,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ static const struct of_device_id blocklist[] __initconst = {
|
|||
|
||||
{ .compatible = "qcom,apq8096", },
|
||||
{ .compatible = "qcom,msm8996", },
|
||||
{ .compatible = "qcom,msm8998", },
|
||||
{ .compatible = "qcom,qcs404", },
|
||||
{ .compatible = "qcom,sa8155p" },
|
||||
{ .compatible = "qcom,sa8540p" },
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -42,7 +42,7 @@ int __drm_mode_object_add(struct drm_device *dev, struct drm_mode_object *obj,
|
|||
{
|
||||
int ret;
|
||||
|
||||
WARN_ON(!dev->driver->load && dev->registered && !obj_free_cb);
|
||||
//WARN_ON(!dev->driver->load && dev->registered && !obj_free_cb);
|
||||
|
||||
mutex_lock(&dev->mode_config.idr_mutex);
|
||||
ret = idr_alloc(&dev->mode_config.object_idr, register_obj ? obj : NULL,
|
||||
|
|
@ -237,10 +237,10 @@ void drm_object_attach_property(struct drm_mode_object *obj,
|
|||
|
||||
|
||||
if (obj->type == DRM_MODE_OBJECT_CONNECTOR) {
|
||||
struct drm_connector *connector = obj_to_connector(obj);
|
||||
/*struct drm_connector *connector = obj_to_connector(obj);
|
||||
|
||||
WARN_ON(!dev->driver->load &&
|
||||
connector->registration_state == DRM_CONNECTOR_REGISTERED);
|
||||
connector->registration_state == DRM_CONNECTOR_REGISTERED);*/
|
||||
} else {
|
||||
WARN_ON(!dev->driver->load && dev->registered);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ config DRM_MSM_DSI_14NM_PHY
|
|||
Choose this option if DSI PHY on 8996 is used on the platform.
|
||||
|
||||
config DRM_MSM_DSI_10NM_PHY
|
||||
bool "Enable DSI 10nm PHY driver in MSM DRM (used by SDM845)"
|
||||
bool "Enable DSI 10nm PHY driver in MSM DRM (used by MSM8998/SDM845)"
|
||||
depends on DRM_MSM_DSI
|
||||
default y
|
||||
help
|
||||
|
|
|
|||
|
|
@ -121,6 +121,48 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit
|
|||
msm_gpu_retire(gpu);
|
||||
}
|
||||
|
||||
static void a5xx_set_pagetable(struct a5xx_gpu *a5xx_gpu,
|
||||
struct msm_ringbuffer *ring, struct msm_file_private *ctx)
|
||||
{
|
||||
phys_addr_t ttbr;
|
||||
u32 asid;
|
||||
u64 memptr = rbmemptr(ring, ttbr0);
|
||||
|
||||
if (ctx == a5xx_gpu->cur_ctx)
|
||||
return;
|
||||
|
||||
if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid))
|
||||
return;
|
||||
|
||||
/* Execute the table update */
|
||||
OUT_PKT7(ring, CP_SMMU_TABLE_UPDATE, 3);
|
||||
OUT_RING(ring, CP_SMMU_TABLE_UPDATE_0_TTBR0_LO(lower_32_bits(ttbr)));
|
||||
|
||||
OUT_RING(ring,
|
||||
CP_SMMU_TABLE_UPDATE_1_TTBR0_HI(upper_32_bits(ttbr)) |
|
||||
CP_SMMU_TABLE_UPDATE_1_ASID(asid));
|
||||
OUT_RING(ring, CP_SMMU_TABLE_UPDATE_2_CONTEXTIDR(0));
|
||||
|
||||
/*
|
||||
* Write the new TTBR0 to the memstore. This is good for debugging.
|
||||
*/
|
||||
OUT_PKT7(ring, CP_MEM_WRITE, 4);
|
||||
OUT_RING(ring, CP_MEM_WRITE_0_ADDR_LO(lower_32_bits(memptr)));
|
||||
OUT_RING(ring, CP_MEM_WRITE_1_ADDR_HI(upper_32_bits(memptr)));
|
||||
OUT_RING(ring, lower_32_bits(ttbr));
|
||||
OUT_RING(ring, (asid << 16) | upper_32_bits(ttbr));
|
||||
|
||||
/*
|
||||
* And finally, trigger a uche flush to be sure there isn't anything
|
||||
* lingering in that part of the GPU
|
||||
*/
|
||||
|
||||
OUT_PKT7(ring, CP_EVENT_WRITE, 1);
|
||||
OUT_RING(ring, 0x31);
|
||||
|
||||
a5xx_gpu->cur_ctx = ctx;
|
||||
}
|
||||
|
||||
static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
|
||||
{
|
||||
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
||||
|
|
@ -151,13 +193,17 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
|
|||
OUT_RING(ring, 1);
|
||||
|
||||
/* Enable local preemption for finegrain preemption */
|
||||
OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1);
|
||||
OUT_RING(ring, 0x02);
|
||||
//OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1);
|
||||
//OUT_RING(ring, 0x02);
|
||||
OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1);
|
||||
OUT_RING(ring, 0x01);
|
||||
|
||||
/* Allow CP_CONTEXT_SWITCH_YIELD packets in the IB2 */
|
||||
OUT_PKT7(ring, CP_YIELD_ENABLE, 1);
|
||||
OUT_RING(ring, 0x02);
|
||||
|
||||
a5xx_set_pagetable(a5xx_gpu, ring, submit->queue->ctx);
|
||||
|
||||
/* Submit the commands */
|
||||
for (i = 0; i < submit->nr_cmds; i++) {
|
||||
switch (submit->cmd[i].type) {
|
||||
|
|
@ -942,6 +988,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
|
|||
a5xx_preempt_fini(gpu);
|
||||
gpu->nr_rings = 1;
|
||||
}
|
||||
a5xx_gpu->cur_ctx = NULL;
|
||||
|
||||
a5xx_preempt_hw_init(gpu);
|
||||
|
||||
|
|
@ -1697,6 +1744,20 @@ static uint32_t a5xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
|
|||
return ring->memptrs->rptr = gpu_read(gpu, REG_A5XX_CP_RB_RPTR);
|
||||
}
|
||||
|
||||
static struct msm_gem_address_space *
|
||||
a5xx_create_private_address_space(struct msm_gpu *gpu)
|
||||
{
|
||||
struct msm_mmu *mmu;
|
||||
|
||||
mmu = msm_iommu_pagetable_create(gpu->aspace->mmu);
|
||||
|
||||
if (IS_ERR(mmu))
|
||||
return ERR_CAST(mmu);
|
||||
|
||||
return msm_gem_address_space_create(mmu,
|
||||
"gpu", 0x100000000ULL, 0x1ffffffffULL);
|
||||
}
|
||||
|
||||
static const struct adreno_gpu_funcs funcs = {
|
||||
.base = {
|
||||
.get_param = adreno_get_param,
|
||||
|
|
@ -1719,6 +1780,7 @@ static const struct adreno_gpu_funcs funcs = {
|
|||
.gpu_state_get = a5xx_gpu_state_get,
|
||||
.gpu_state_put = a5xx_gpu_state_put,
|
||||
.create_address_space = adreno_iommu_create_address_space,
|
||||
.create_private_address_space = a5xx_create_private_address_space,
|
||||
.get_rptr = a5xx_get_rptr,
|
||||
},
|
||||
.get_timestamp = a5xx_get_timestamp,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ struct a5xx_gpu {
|
|||
|
||||
struct msm_ringbuffer *cur_ring;
|
||||
struct msm_ringbuffer *next_ring;
|
||||
struct msm_file_private *cur_ctx;
|
||||
|
||||
struct drm_gem_object *preempt_bo[MSM_GPU_MAX_RINGS];
|
||||
struct drm_gem_object *preempt_counters_bo[MSM_GPU_MAX_RINGS];
|
||||
|
|
|
|||
|
|
@ -355,6 +355,11 @@ MODULE_FIRMWARE("qcom/a530_zap.mdt");
|
|||
MODULE_FIRMWARE("qcom/a530_zap.b00");
|
||||
MODULE_FIRMWARE("qcom/a530_zap.b01");
|
||||
MODULE_FIRMWARE("qcom/a530_zap.b02");
|
||||
MODULE_FIRMWARE("qcom/a540_gpmu.fw2");
|
||||
MODULE_FIRMWARE("qcom/a540_zap.mdt");
|
||||
MODULE_FIRMWARE("qcom/a540_zap.b00");
|
||||
MODULE_FIRMWARE("qcom/a540_zap.b01");
|
||||
MODULE_FIRMWARE("qcom/a540_zap.b02");
|
||||
MODULE_FIRMWARE("qcom/a630_sqe.fw");
|
||||
MODULE_FIRMWARE("qcom/a630_gmu.bin");
|
||||
MODULE_FIRMWARE("qcom/a630_zap.mbn");
|
||||
|
|
|
|||
|
|
@ -743,6 +743,7 @@ struct dpu_mdss_cfg {
|
|||
const struct dpu_mdp_cfg *mdp;
|
||||
|
||||
u32 ctl_count;
|
||||
bool ctl_no_start_read_quirk;
|
||||
const struct dpu_ctl_cfg *ctl;
|
||||
|
||||
u32 sspp_count;
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ static inline void dpu_hw_ctl_trigger_start(struct dpu_hw_ctl *ctx)
|
|||
|
||||
static inline bool dpu_hw_ctl_is_started(struct dpu_hw_ctl *ctx)
|
||||
{
|
||||
return !!(DPU_REG_READ(&ctx->hw, CTL_START) & BIT(0));
|
||||
return !!(DPU_REG_READ(&ctx->hw, CTL_START) & BIT(0)) || ctx->ctl_no_start_read_quirk;
|
||||
}
|
||||
|
||||
static inline void dpu_hw_ctl_trigger_pending(struct dpu_hw_ctl *ctx)
|
||||
|
|
@ -628,6 +628,7 @@ struct dpu_hw_ctl *dpu_hw_ctl_init(enum dpu_ctl idx,
|
|||
c->idx = idx;
|
||||
c->mixer_count = m->mixer_count;
|
||||
c->mixer_hw_caps = m->mixer;
|
||||
c->ctl_no_start_read_quirk = m->ctl_no_start_read_quirk;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@ struct dpu_hw_ctl {
|
|||
u32 pending_flush_mask;
|
||||
u32 pending_intf_flush_mask;
|
||||
u32 pending_merge_3d_flush_mask;
|
||||
bool ctl_no_start_read_quirk;
|
||||
|
||||
/* ops */
|
||||
struct dpu_hw_ctl_ops ops;
|
||||
|
|
|
|||
|
|
@ -1072,6 +1072,10 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
|
|||
goto power_error;
|
||||
}
|
||||
|
||||
if (of_property_read_bool(dpu_kms->pdev->dev.of_node, "qcom,ctl-no-start-read-quirk")) {
|
||||
dpu_kms->catalog->ctl_no_start_read_quirk = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we need to read the HW catalog and initialize resources such as
|
||||
* clocks, regulators, GDSC/MMAGIC, ioremap the register ranges etc
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_10nm *pll, struct dsi_pll_confi
|
|||
|
||||
pll_freq = pll->vco_current_rate;
|
||||
|
||||
divider = fref * 2;
|
||||
divider = fref;
|
||||
|
||||
multiplier = 1 << FRAC_BITS;
|
||||
dec_multiple = div_u64(pll_freq * multiplier, divider);
|
||||
|
|
@ -440,12 +440,11 @@ static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw,
|
|||
* 1. Assumes prescaler is disabled
|
||||
*/
|
||||
multiplier = 1 << FRAC_BITS;
|
||||
pll_freq = dec * (ref_clk * 2);
|
||||
tmp64 = (ref_clk * 2 * frac);
|
||||
pll_freq = dec * ref_clk;
|
||||
tmp64 = ref_clk * frac;
|
||||
pll_freq += div_u64(tmp64, multiplier);
|
||||
|
||||
vco_rate = pll_freq;
|
||||
pll_10nm->vco_current_rate = vco_rate;
|
||||
|
||||
DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x",
|
||||
pll_10nm->phy->id, (unsigned long)vco_rate, dec, frac);
|
||||
|
|
|
|||
|
|
@ -461,6 +461,36 @@ config DRM_PANEL_SAMSUNG_S6D27A1
|
|||
This panel can be found in Samsung Galaxy Ace 2
|
||||
GT-I8160 mobile phone.
|
||||
|
||||
config DRM_PANEL_SAMSUNG_S6E3FA5
|
||||
tristate "Samsung S6E3FA5 DSI command mode panel"
|
||||
depends on OF
|
||||
depends on DRM_MIPI_DSI
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
select VIDEOMODE_HELPERS
|
||||
help
|
||||
Say Y here if you want to enable support for Samsung S6E3FA5 AMOLED
|
||||
command mode panel as found in OnePlus 5 (2017) devices. The panel has a
|
||||
FHD (1080x1920) resolution and uses 24 bit RGB per pixel. It provides a
|
||||
MIPI DSI interface to the host and has a built-in LED backlight.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called panel-samsung-s6e3fa5.
|
||||
|
||||
config DRM_PANEL_SAMSUNG_S6E3FC1
|
||||
tristate "Samsung S6E3FC1 DSI command mode panel"
|
||||
depends on OF
|
||||
depends on DRM_MIPI_DSI
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
select VIDEOMODE_HELPERS
|
||||
help
|
||||
Say Y here if you want to enable support for Samsung S6E3FC1 AMOLED
|
||||
command mode panel as found in OnePlus 5T (2017) devices. The panel has a
|
||||
FHD (1080x2160) resolution and uses 24 bit RGB per pixel. It provides a
|
||||
MIPI DSI interface to the host and has a built-in LED backlight.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called panel-samsung-s6e3fc1.
|
||||
|
||||
config DRM_PANEL_SAMSUNG_S6E3HA2
|
||||
tristate "Samsung S6E3HA2 DSI video mode panel"
|
||||
depends on OF
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o
|
|||
obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
|
||||
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D16D0) += panel-samsung-s6d16d0.o
|
||||
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D27A1) += panel-samsung-s6d27a1.o
|
||||
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3FA5) += panel-samsung-s6e3fa5.o
|
||||
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3FC1) += panel-samsung-s6e3fc1.o
|
||||
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o
|
||||
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o
|
||||
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63M0) += panel-samsung-s6e63m0.o
|
||||
|
|
|
|||
351
drivers/gpu/drm/panel/panel-samsung-s6e3fa5.c
Normal file
351
drivers/gpu/drm/panel/panel-samsung-s6e3fa5.c
Normal file
|
|
@ -0,0 +1,351 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2021 Jami Kettunen <jami.kettunen@protonmail.com>
|
||||
* Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <video/mipi_display.h>
|
||||
|
||||
#include <drm/drm_connector.h>
|
||||
#include <drm/drm_mipi_dsi.h>
|
||||
#include <drm/drm_modes.h>
|
||||
#include <drm/drm_panel.h>
|
||||
|
||||
struct s6e3fa5 {
|
||||
struct drm_panel panel;
|
||||
enum drm_panel_orientation orientation;
|
||||
struct mipi_dsi_device *dsi;
|
||||
struct regulator *supply;
|
||||
struct gpio_desc *reset_gpio;
|
||||
bool prepared;
|
||||
};
|
||||
|
||||
static inline struct s6e3fa5 *to_s6e3fa5_panel(struct drm_panel *panel)
|
||||
{
|
||||
return container_of(panel, struct s6e3fa5, panel);
|
||||
}
|
||||
|
||||
#define dsi_dcs_write_seq(dsi, seq...) do { \
|
||||
static const u8 d[] = { seq }; \
|
||||
int ret; \
|
||||
ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
|
||||
if (ret < 0) \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
static void s6e3fa5_reset(struct s6e3fa5 *ctx)
|
||||
{
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
usleep_range(2000, 3000);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
usleep_range(2000, 3000);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
usleep_range(2000, 3000);
|
||||
}
|
||||
|
||||
static int s6e3fa5_on(struct s6e3fa5 *ctx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = ctx->dsi;
|
||||
struct device *dev = &dsi->dev;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(20);
|
||||
|
||||
ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set tear on: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dsi_dcs_write_seq(dsi, 0xf0, 0x5a, 0x5a);
|
||||
dsi_dcs_write_seq(dsi, 0xb0, 0x04);
|
||||
dsi_dcs_write_seq(dsi, 0xb4, 0x06, 0x0c, 0x12);
|
||||
dsi_dcs_write_seq(dsi, 0xf0, 0xa5, 0xa5);
|
||||
dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20);
|
||||
dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_POWER_SAVE, 0x00);
|
||||
dsi_dcs_write_seq(dsi, 0xf0, 0x5a, 0x5a);
|
||||
dsi_dcs_write_seq(dsi, 0xc3, 0x01);
|
||||
dsi_dcs_write_seq(dsi, 0xb0, 0x18);
|
||||
dsi_dcs_write_seq(dsi, 0xc3, 0x00);
|
||||
dsi_dcs_write_seq(dsi, 0xf0, 0xa5, 0xa5);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set display on: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fa5_off(struct s6e3fa5 *ctx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = ctx->dsi;
|
||||
struct device *dev = &dsi->dev;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_off(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set display off: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(40);
|
||||
|
||||
ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enter sleep mode: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(160);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fa5_prepare(struct drm_panel *panel)
|
||||
{
|
||||
struct s6e3fa5 *ctx = to_s6e3fa5_panel(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = regulator_enable(ctx->supply);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enable regulator: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
s6e3fa5_reset(ctx);
|
||||
|
||||
ret = s6e3fa5_on(ctx);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to initialize panel: %d\n", ret);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
regulator_disable(ctx->supply);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx->prepared = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fa5_unprepare(struct drm_panel *panel)
|
||||
{
|
||||
struct s6e3fa5 *ctx = to_s6e3fa5_panel(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (!ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = s6e3fa5_off(ctx);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "Failed to un-initialize panel: %d\n", ret);
|
||||
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
regulator_disable(ctx->supply);
|
||||
|
||||
ctx->prepared = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_display_mode s6e3fa5_mode = {
|
||||
.clock = (1080 + 120 + 19 + 70) * (1920 + 18 + 2 + 4) * 60 / 1000,
|
||||
.hdisplay = 1080,
|
||||
.hsync_start = 1080 + 120,
|
||||
.hsync_end = 1080 + 120 + 19,
|
||||
.htotal = 1080 + 120 + 19 + 70,
|
||||
.vdisplay = 1920,
|
||||
.vsync_start = 1920 + 18,
|
||||
.vsync_end = 1920 + 18 + 2,
|
||||
.vtotal = 1920 + 18 + 2 + 4,
|
||||
.width_mm = 68,
|
||||
.height_mm = 122,
|
||||
};
|
||||
|
||||
static int s6e3fa5_get_modes(struct drm_panel *panel,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
struct s6e3fa5 *ctx;
|
||||
|
||||
mode = drm_mode_duplicate(connector->dev, &s6e3fa5_mode);
|
||||
if (!mode)
|
||||
return -ENOMEM;
|
||||
ctx = to_s6e3fa5_panel(panel);
|
||||
|
||||
drm_mode_set_name(mode);
|
||||
|
||||
mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
|
||||
connector->display_info.width_mm = mode->width_mm;
|
||||
connector->display_info.height_mm = mode->height_mm;
|
||||
drm_connector_set_panel_orientation(connector, ctx->orientation);
|
||||
drm_mode_probed_add(connector, mode);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct drm_panel_funcs s6e3fa5_panel_funcs = {
|
||||
.prepare = s6e3fa5_prepare,
|
||||
.unprepare = s6e3fa5_unprepare,
|
||||
.get_modes = s6e3fa5_get_modes,
|
||||
};
|
||||
|
||||
static int s6e3fa5_bl_update_status(struct backlight_device *bl)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = bl_get_data(bl);
|
||||
u16 brightness = backlight_get_brightness(bl);
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_brightness(dsi, brightness);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fa5_bl_get_brightness(struct backlight_device *bl)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = bl_get_data(bl);
|
||||
u16 brightness;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
return brightness & 0xff;
|
||||
}
|
||||
|
||||
static const struct backlight_ops s6e3fa5_bl_ops = {
|
||||
.update_status = s6e3fa5_bl_update_status,
|
||||
.get_brightness = s6e3fa5_bl_get_brightness,
|
||||
};
|
||||
|
||||
static struct backlight_device *
|
||||
s6e3fa5_create_backlight(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
const struct backlight_properties props = {
|
||||
.type = BACKLIGHT_RAW,
|
||||
.brightness = 255,
|
||||
.max_brightness = 255,
|
||||
};
|
||||
|
||||
return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
|
||||
&s6e3fa5_bl_ops, &props);
|
||||
}
|
||||
|
||||
static int s6e3fa5_probe(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
struct s6e3fa5 *ctx;
|
||||
int ret;
|
||||
|
||||
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->supply = devm_regulator_get(dev, "vddio");
|
||||
if (IS_ERR(ctx->supply))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->supply),
|
||||
"Failed to get vddio regulator\n");
|
||||
|
||||
ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(ctx->reset_gpio))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),
|
||||
"Failed to get reset-gpios\n");
|
||||
|
||||
ctx->dsi = dsi;
|
||||
mipi_dsi_set_drvdata(dsi, ctx);
|
||||
|
||||
dsi->lanes = 4;
|
||||
dsi->format = MIPI_DSI_FMT_RGB888;
|
||||
dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_VIDEO_HSE |
|
||||
MIPI_DSI_MODE_NO_EOT_PACKET |
|
||||
MIPI_DSI_CLOCK_NON_CONTINUOUS;
|
||||
|
||||
ret = of_drm_get_panel_orientation(dev->of_node, &ctx->orientation);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to parse rotation property: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_panel_init(&ctx->panel, dev, &s6e3fa5_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ctx->panel.backlight = s6e3fa5_create_backlight(dsi);
|
||||
if (IS_ERR(ctx->panel.backlight))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight),
|
||||
"Failed to create backlight\n");
|
||||
|
||||
drm_panel_add(&ctx->panel);
|
||||
|
||||
ret = mipi_dsi_attach(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
|
||||
drm_panel_remove(&ctx->panel);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fa5_remove(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct s6e3fa5 *ctx = mipi_dsi_get_drvdata(dsi);
|
||||
int ret;
|
||||
|
||||
ret = mipi_dsi_detach(dsi);
|
||||
if (ret < 0)
|
||||
dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
|
||||
|
||||
drm_panel_remove(&ctx->panel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id s6e3fa5_of_match[] = {
|
||||
{ .compatible = "samsung,s6e3fa5" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, s6e3fa5_of_match);
|
||||
|
||||
static struct mipi_dsi_driver s6e3fa5_driver = {
|
||||
.probe = s6e3fa5_probe,
|
||||
.remove = s6e3fa5_remove,
|
||||
.driver = {
|
||||
.name = "panel-samsung-s6e3fa5",
|
||||
.of_match_table = s6e3fa5_of_match,
|
||||
},
|
||||
};
|
||||
module_mipi_dsi_driver(s6e3fa5_driver);
|
||||
|
||||
MODULE_AUTHOR("Jami Kettunen <jami.kettunen@protonmail.com>");
|
||||
MODULE_DESCRIPTION("DRM driver for Samsung S6E3FA5 AMOLED DSI cmd mode panel found on OnePlus 5 phones");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
345
drivers/gpu/drm/panel/panel-samsung-s6e3fc1.c
Normal file
345
drivers/gpu/drm/panel/panel-samsung-s6e3fc1.c
Normal file
|
|
@ -0,0 +1,345 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2021 Jami Kettunen <jami.kettunen@protonmail.com>
|
||||
* Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/swab.h>
|
||||
|
||||
#include <video/mipi_display.h>
|
||||
|
||||
#include <drm/drm_mipi_dsi.h>
|
||||
#include <drm/drm_modes.h>
|
||||
#include <drm/drm_panel.h>
|
||||
|
||||
struct s6e3fc1 {
|
||||
struct drm_panel panel;
|
||||
struct mipi_dsi_device *dsi;
|
||||
struct regulator *supply;
|
||||
struct gpio_desc *reset_gpio;
|
||||
bool prepared;
|
||||
};
|
||||
|
||||
static inline struct s6e3fc1 *to_s6e3fc1_panel(struct drm_panel *panel)
|
||||
{
|
||||
return container_of(panel, struct s6e3fc1, panel);
|
||||
}
|
||||
|
||||
#define dsi_dcs_write_seq(dsi, seq...) do { \
|
||||
static const u8 d[] = { seq }; \
|
||||
int ret; \
|
||||
ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
|
||||
if (ret < 0) \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
static void s6e3fc1_reset(struct s6e3fc1 *ctx)
|
||||
{
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
usleep_range(2000, 3000);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
usleep_range(2000, 3000);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
|
||||
usleep_range(2000, 3000);
|
||||
}
|
||||
|
||||
static int s6e3fc1_on(struct s6e3fc1 *ctx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = ctx->dsi;
|
||||
struct device *dev = &dsi->dev;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(25);
|
||||
|
||||
ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set tear on: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dsi_dcs_write_seq(dsi, 0xfc, 0x5a, 0x5a);
|
||||
dsi_dcs_write_seq(dsi, 0xe8, 0x64, 0x08, 0x0c);
|
||||
dsi_dcs_write_seq(dsi, 0xfc, 0xa5, 0xa5);
|
||||
dsi_dcs_write_seq(dsi, 0xf0, 0x5a, 0x5a);
|
||||
dsi_dcs_write_seq(dsi, 0xb0, 0x01);
|
||||
dsi_dcs_write_seq(dsi, 0xed, 0x04);
|
||||
dsi_dcs_write_seq(dsi, 0xf0, 0xa5, 0xa5);
|
||||
dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20);
|
||||
dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_POWER_SAVE, 0x00);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set display on: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fc1_off(struct s6e3fc1 *ctx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = ctx->dsi;
|
||||
struct device *dev = &dsi->dev;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_off(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set display off: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
usleep_range(10000, 11000);
|
||||
|
||||
ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enter sleep mode: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(160);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fc1_prepare(struct drm_panel *panel)
|
||||
{
|
||||
struct s6e3fc1 *ctx = to_s6e3fc1_panel(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = regulator_enable(ctx->supply);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enable regulator: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
s6e3fc1_reset(ctx);
|
||||
|
||||
ret = s6e3fc1_on(ctx);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to initialize panel: %d\n", ret);
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
regulator_disable(ctx->supply);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx->prepared = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fc1_unprepare(struct drm_panel *panel)
|
||||
{
|
||||
struct s6e3fc1 *ctx = to_s6e3fc1_panel(panel);
|
||||
struct device *dev = &ctx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (!ctx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = s6e3fc1_off(ctx);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "Failed to un-initialize panel: %d\n", ret);
|
||||
|
||||
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
|
||||
regulator_disable(ctx->supply);
|
||||
|
||||
ctx->prepared = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_display_mode s6e3fc1_mode = {
|
||||
.clock = (1080 + 128 + 16 + 64) * (2160 + 18 + 2 + 4) * 60 / 1000,
|
||||
.hdisplay = 1080,
|
||||
.hsync_start = 1080 + 128,
|
||||
.hsync_end = 1080 + 128 + 16,
|
||||
.htotal = 1080 + 128 + 16 + 64,
|
||||
.vdisplay = 2160,
|
||||
.vsync_start = 2160 + 18,
|
||||
.vsync_end = 2160 + 18 + 2,
|
||||
.vtotal = 2160 + 18 + 2 + 4,
|
||||
.width_mm = 68,
|
||||
.height_mm = 137,
|
||||
};
|
||||
|
||||
static int s6e3fc1_get_modes(struct drm_panel *panel,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_mode_duplicate(connector->dev, &s6e3fc1_mode);
|
||||
if (!mode)
|
||||
return -ENOMEM;
|
||||
|
||||
drm_mode_set_name(mode);
|
||||
|
||||
mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
|
||||
connector->display_info.width_mm = mode->width_mm;
|
||||
connector->display_info.height_mm = mode->height_mm;
|
||||
drm_mode_probed_add(connector, mode);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct drm_panel_funcs s6e3fc1_panel_funcs = {
|
||||
.prepare = s6e3fc1_prepare,
|
||||
.unprepare = s6e3fc1_unprepare,
|
||||
.get_modes = s6e3fc1_get_modes,
|
||||
};
|
||||
|
||||
static int s6e3fc1_bl_update_status(struct backlight_device *bl)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = bl_get_data(bl);
|
||||
u16 brightness;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
|
||||
brightness = (u16)backlight_get_brightness(bl);
|
||||
// This panel needs the high and low bytes swapped for the brightness value
|
||||
brightness = __swab16(brightness);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_brightness(dsi, brightness);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fc1_bl_get_brightness(struct backlight_device *bl)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = bl_get_data(bl);
|
||||
u16 brightness;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
// This panel needs the high and low bytes swapped for the brightness value
|
||||
brightness = __swab16(brightness);
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
return brightness;
|
||||
}
|
||||
|
||||
static const struct backlight_ops s6e3fc1_bl_ops = {
|
||||
.update_status = s6e3fc1_bl_update_status,
|
||||
.get_brightness = s6e3fc1_bl_get_brightness,
|
||||
};
|
||||
|
||||
static struct backlight_device *
|
||||
s6e3fc1_create_backlight(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
const struct backlight_properties props = {
|
||||
.type = BACKLIGHT_RAW,
|
||||
.brightness = 1023,
|
||||
.max_brightness = 1023,
|
||||
};
|
||||
|
||||
return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
|
||||
&s6e3fc1_bl_ops, &props);
|
||||
}
|
||||
|
||||
static int s6e3fc1_probe(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
struct s6e3fc1 *ctx;
|
||||
int ret;
|
||||
|
||||
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->supply = devm_regulator_get(dev, "vddio");
|
||||
if (IS_ERR(ctx->supply))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->supply),
|
||||
"Failed to get vddio regulator\n");
|
||||
|
||||
ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(ctx->reset_gpio))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),
|
||||
"Failed to get reset-gpios\n");
|
||||
|
||||
ctx->dsi = dsi;
|
||||
mipi_dsi_set_drvdata(dsi, ctx);
|
||||
|
||||
dsi->lanes = 4;
|
||||
dsi->format = MIPI_DSI_FMT_RGB888;
|
||||
dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_VIDEO_HSE |
|
||||
MIPI_DSI_CLOCK_NON_CONTINUOUS;
|
||||
|
||||
drm_panel_init(&ctx->panel, dev, &s6e3fc1_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
ctx->panel.backlight = s6e3fc1_create_backlight(dsi);
|
||||
if (IS_ERR(ctx->panel.backlight))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight),
|
||||
"Failed to create backlight\n");
|
||||
|
||||
drm_panel_add(&ctx->panel);
|
||||
|
||||
ret = mipi_dsi_attach(dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
|
||||
drm_panel_remove(&ctx->panel);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s6e3fc1_remove(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct s6e3fc1 *ctx = mipi_dsi_get_drvdata(dsi);
|
||||
int ret;
|
||||
|
||||
ret = mipi_dsi_detach(dsi);
|
||||
if (ret < 0)
|
||||
dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
|
||||
|
||||
drm_panel_remove(&ctx->panel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id s6e3fc1_of_match[] = {
|
||||
{ .compatible = "samsung,s6e3fc1" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, s6e3fc1_of_match);
|
||||
|
||||
static struct mipi_dsi_driver s6e3fc1_driver = {
|
||||
.probe = s6e3fc1_probe,
|
||||
.remove = s6e3fc1_remove,
|
||||
.driver = {
|
||||
.name = "panel-samsung-s6e3fc1",
|
||||
.of_match_table = s6e3fc1_of_match,
|
||||
},
|
||||
};
|
||||
module_mipi_dsi_driver(s6e3fc1_driver);
|
||||
|
||||
MODULE_AUTHOR("Jami Kettunen <jami.kettunen@protonmail.com>");
|
||||
MODULE_DESCRIPTION("DRM driver for Samsung S6E3FC1 AMOLED DSI cmd mode panel found on OnePlus 5T phones");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
@ -227,6 +227,17 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
|
|||
dev_dbg(dev, "sid 0x%x status 0x%x\n",
|
||||
cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
|
||||
}
|
||||
if (privdata->mp2_ops->discovery_status &&
|
||||
privdata->mp2_ops->discovery_status(privdata) == 0) {
|
||||
amd_sfh_hid_client_deinit(privdata);
|
||||
for (i = 0; i < cl_data->num_hid_devices; i++) {
|
||||
devm_kfree(dev, cl_data->feature_report[i]);
|
||||
devm_kfree(dev, in_data->input_report[i]);
|
||||
devm_kfree(dev, cl_data->report_descr[i]);
|
||||
}
|
||||
dev_warn(dev, "Failed to discover, sensors not enabled\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
schedule_delayed_work(&cl_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -130,6 +130,12 @@ static int amd_sfh_irq_init_v2(struct amd_mp2_dev *privdata)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int amd_sfh_dis_sts_v2(struct amd_mp2_dev *privdata)
|
||||
{
|
||||
return (readl(privdata->mmio + AMD_P2C_MSG(1)) &
|
||||
SENSOR_DISCOVERY_STATUS_MASK) >> SENSOR_DISCOVERY_STATUS_SHIFT;
|
||||
}
|
||||
|
||||
void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info)
|
||||
{
|
||||
union sfh_cmd_param cmd_param;
|
||||
|
|
@ -245,6 +251,7 @@ static const struct amd_mp2_ops amd_sfh_ops_v2 = {
|
|||
.response = amd_sfh_wait_response_v2,
|
||||
.clear_intr = amd_sfh_clear_intr_v2,
|
||||
.init_intr = amd_sfh_irq_init_v2,
|
||||
.discovery_status = amd_sfh_dis_sts_v2,
|
||||
};
|
||||
|
||||
static const struct amd_mp2_ops amd_sfh_ops = {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@
|
|||
|
||||
#define AMD_SFH_IDLE_LOOP 200
|
||||
|
||||
#define SENSOR_DISCOVERY_STATUS_MASK GENMASK(5, 3)
|
||||
#define SENSOR_DISCOVERY_STATUS_SHIFT 3
|
||||
|
||||
/* SFH Command register */
|
||||
union sfh_cmd_base {
|
||||
u32 ul;
|
||||
|
|
@ -143,5 +146,6 @@ struct amd_mp2_ops {
|
|||
int (*response)(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts);
|
||||
void (*clear_intr)(struct amd_mp2_dev *privdata);
|
||||
int (*init_intr)(struct amd_mp2_dev *privdata);
|
||||
int (*discovery_status)(struct amd_mp2_dev *privdata);
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@
|
|||
#define QUP_MX_READ_CNT 0x208
|
||||
#define QUP_IN_FIFO_BASE 0x218
|
||||
#define QUP_I2C_CLK_CTL 0x400
|
||||
#define QUP_I2C_CLK_CTL_SDA_NR GENMASK(27, 26)
|
||||
#define QUP_I2C_CLK_CTL_SCL_NR GENMASK(25, 24)
|
||||
#define QUP_I2C_STATUS 0x404
|
||||
#define QUP_I2C_MASTER_GEN 0x408
|
||||
|
||||
|
|
@ -1663,6 +1665,7 @@ static int qup_i2c_probe(struct platform_device *pdev)
|
|||
int ret, fs_div, hs_div;
|
||||
u32 src_clk_freq = DEFAULT_SRC_CLK;
|
||||
u32 clk_freq = DEFAULT_CLK_FREQ;
|
||||
u32 noise_reject_scl = 0, noise_reject_sda = 0;
|
||||
int blocks;
|
||||
bool is_qup_v1;
|
||||
|
||||
|
|
@ -1860,6 +1863,19 @@ nodma:
|
|||
qup->clk_ctl = ((fs_div / 2) << 16) | (hs_div << 8) | (fs_div & 0xff);
|
||||
}
|
||||
|
||||
/* SCL/SDA Noise rejection (optional) */
|
||||
ret = device_property_read_u32(qup->dev, "qcom,noise-reject-scl",
|
||||
&noise_reject_scl);
|
||||
if (ret == 0)
|
||||
qup->clk_ctl |= FIELD_PREP(QUP_I2C_CLK_CTL_SCL_NR,
|
||||
noise_reject_scl);
|
||||
|
||||
ret = device_property_read_u32(qup->dev, "qcom,noise-reject-sda",
|
||||
&noise_reject_sda);
|
||||
if (ret == 0)
|
||||
qup->clk_ctl |= FIELD_PREP(QUP_I2C_CLK_CTL_SDA_NR,
|
||||
noise_reject_sda);
|
||||
|
||||
/*
|
||||
* Time it takes for a byte to be clocked out on the bus.
|
||||
* Each byte takes 9 clock cycles (8 bits + 1 ack).
|
||||
|
|
|
|||
|
|
@ -823,6 +823,18 @@ config QCOM_PM8XXX_XOADC
|
|||
To compile this driver as a module, choose M here: the module
|
||||
will be called qcom-pm8xxx-xoadc.
|
||||
|
||||
config QCOM_SPMI_RRADC
|
||||
tristate "Qualcomm SPMI RRADC"
|
||||
depends on MFD_SPMI_PMIC
|
||||
help
|
||||
This is for the PMIC Round Robin ADC driver.
|
||||
|
||||
This driver exposes the battery ID resistor, battery thermal, PMIC die
|
||||
temperature, charger USB in and DC in voltage and current.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called qcom-qpmi-rradc.
|
||||
|
||||
config QCOM_SPMI_IADC
|
||||
tristate "Qualcomm SPMI PMIC current ADC"
|
||||
depends on SPMI
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ obj-$(CONFIG_NPCM_ADC) += npcm_adc.o
|
|||
obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o
|
||||
obj-$(CONFIG_QCOM_SPMI_ADC5) += qcom-spmi-adc5.o
|
||||
obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
|
||||
obj-$(CONFIG_QCOM_SPMI_RRADC) += qcom-spmi-rradc.o
|
||||
obj-$(CONFIG_QCOM_VADC_COMMON) += qcom-vadc-common.o
|
||||
obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
|
||||
obj-$(CONFIG_QCOM_PM8XXX_XOADC) += qcom-pm8xxx-xoadc.o
|
||||
|
|
|
|||
1021
drivers/iio/adc/qcom-spmi-rradc.c
Normal file
1021
drivers/iio/adc/qcom-spmi-rradc.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -243,6 +243,19 @@ config KEYBOARD_GPIO
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called gpio_keys.
|
||||
|
||||
config KEYBOARD_GPIO_FASTMATRIX
|
||||
tristate "GPIO Keyboard"
|
||||
depends on GPIOLIB
|
||||
select INPUT_MATRIXKMAP
|
||||
help
|
||||
This driver implements support for matrix keypads and/or
|
||||
keyboards connected directly to GPIO pins of a CPU, made
|
||||
to also perform with slow I2C GPIO expanders and even
|
||||
on matrices with no protection diodes.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called gpio_fastmatrix
|
||||
|
||||
config KEYBOARD_GPIO_POLLED
|
||||
tristate "Polled GPIO buttons"
|
||||
depends on GPIOLIB
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ obj-$(CONFIG_KEYBOARD_DLINK_DIR685) += dlink-dir685-touchkeys.o
|
|||
obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o
|
||||
obj-$(CONFIG_KEYBOARD_GOLDFISH_EVENTS) += goldfish_events.o
|
||||
obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
|
||||
obj-$(CONFIG_KEYBOARD_GPIO_FASTMATRIX) += gpio_fastmatrix.o
|
||||
obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o
|
||||
obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o
|
||||
obj-$(CONFIG_KEYBOARD_TCA8418) += tca8418_keypad.o
|
||||
|
|
|
|||
528
drivers/input/keyboard/gpio_fastmatrix.c
Normal file
528
drivers/input/keyboard/gpio_fastmatrix.c
Normal file
|
|
@ -0,0 +1,528 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Fast GPIO driven keyboard/keypad matrix driver
|
||||
*
|
||||
* Copyright (c) 2020 AngeloGioacchino Del Regno
|
||||
* <angelogioacchino.delregno@somainline.org>
|
||||
* Based on matrix_keypad.c
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input/matrix_keypad.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
|
||||
struct gpio_keyboard {
|
||||
struct device *dev;
|
||||
struct input_dev *input_dev;
|
||||
unsigned int row_shift;
|
||||
|
||||
struct gpio_descs *row_gpios;
|
||||
struct gpio_descs *col_gpios;
|
||||
u32 autorescan_ms;
|
||||
u32 debounce_ms;
|
||||
u32 col_scan_us;
|
||||
int clustered_irq;
|
||||
|
||||
DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS);
|
||||
|
||||
u32 last_key_state[MATRIX_MAX_COLS];
|
||||
struct delayed_work work;
|
||||
struct mutex lock;
|
||||
|
||||
bool drive_inactive_cols;
|
||||
bool gpio_all_disabled;
|
||||
bool scan_pending;
|
||||
bool stopped;
|
||||
};
|
||||
|
||||
static int activate_one_column(struct gpio_keyboard *gkb, int col, bool wait)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = gpiod_direction_output(gkb->col_gpios->desc[col], 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (wait && gkb->col_scan_us)
|
||||
udelay(gkb->col_scan_us);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: If drive_inactive_cols is false, then the GPIO has to be put into
|
||||
* HiZ when de-activated to cause minmal side effect when scanning other
|
||||
* columns. In that case it is configured here to be input, otherwise it is
|
||||
* driven with the inactive value.
|
||||
*/
|
||||
static int deactivate_one_column(struct gpio_keyboard *gkb, int col)
|
||||
{
|
||||
gpiod_set_value_cansleep(gkb->col_gpios->desc[col], 0);
|
||||
if (!gkb->drive_inactive_cols)
|
||||
return gpiod_direction_input(gkb->col_gpios->desc[col]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int activate_all_cols(struct gpio_keyboard *gkb)
|
||||
{
|
||||
unsigned long val = ULONG_MAX;
|
||||
int ret, col;
|
||||
|
||||
/*
|
||||
* Shortcut! If we don't have to set direction, we can use
|
||||
* the way faster gpiod array setting instead.
|
||||
*/
|
||||
if (gkb->drive_inactive_cols) {
|
||||
return gpiod_set_array_value_cansleep(gkb->col_gpios->ndescs,
|
||||
gkb->col_gpios->desc,
|
||||
gkb->col_gpios->info,
|
||||
&val);
|
||||
}
|
||||
|
||||
for (col = 0; col < gkb->col_gpios->ndescs; col++) {
|
||||
ret = activate_one_column(gkb, col, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deactivate_all_cols(struct gpio_keyboard *gkb)
|
||||
{
|
||||
unsigned long val = 0;
|
||||
int col, ret;
|
||||
|
||||
/*
|
||||
* If the GPIO controller supports setting all pins at once it
|
||||
* is going to be way faster, otherwise this function will fall
|
||||
* back to setting all pins one at a time.
|
||||
*/
|
||||
ret = gpiod_set_array_value_cansleep(gkb->col_gpios->ndescs,
|
||||
gkb->col_gpios->desc,
|
||||
gkb->col_gpios->info, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!gkb->drive_inactive_cols) {
|
||||
for (col = 0; col < gkb->col_gpios->ndescs; col++)
|
||||
gpiod_direction_input(gkb->col_gpios->desc[col]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void enable_row_irqs(struct gpio_keyboard *gkb)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (gkb->clustered_irq > 0)
|
||||
enable_irq(gkb->clustered_irq);
|
||||
else {
|
||||
for (i = 0; i < gkb->row_gpios->ndescs; i++)
|
||||
enable_irq(gpiod_to_irq(gkb->row_gpios->desc[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static void disable_row_irqs(struct gpio_keyboard *gkb)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (gkb->clustered_irq > 0)
|
||||
disable_irq_nosync(gkb->clustered_irq);
|
||||
else {
|
||||
for (i = 0; i < gkb->row_gpios->ndescs; i++)
|
||||
disable_irq_nosync(gpiod_to_irq(gkb->row_gpios->desc[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This gets the keys from keyboard and reports it to input subsystem
|
||||
*/
|
||||
static void gpio_keyboard_scan(struct work_struct *work)
|
||||
{
|
||||
struct gpio_keyboard *gkb =
|
||||
container_of(work, struct gpio_keyboard, work.work);
|
||||
struct input_dev *input_dev = gkb->input_dev;
|
||||
const unsigned short *keycodes = input_dev->keycode;
|
||||
u32 *new_state;
|
||||
unsigned long row_values;
|
||||
int ret, row, col, code;
|
||||
u32 keymask = 0;
|
||||
|
||||
new_state = kzalloc(gkb->col_gpios->ndescs * sizeof(*new_state),
|
||||
GFP_KERNEL);
|
||||
if (!new_state)
|
||||
return;
|
||||
|
||||
/* de-activate all columns for scanning */
|
||||
deactivate_all_cols(gkb);
|
||||
|
||||
/* assert each column and read the row status out */
|
||||
for (col = 0; col < gkb->col_gpios->ndescs; col++) {
|
||||
activate_one_column(gkb, col, true);
|
||||
|
||||
ret = gpiod_get_array_value_cansleep(gkb->row_gpios->ndescs,
|
||||
gkb->row_gpios->desc,
|
||||
gkb->row_gpios->info,
|
||||
&row_values);
|
||||
new_state[col] = row_values;
|
||||
keymask |= new_state[col];
|
||||
|
||||
if (deactivate_one_column(gkb, col)) {
|
||||
activate_all_cols(gkb);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
activate_all_cols(gkb);
|
||||
|
||||
for (col = 0; col < gkb->col_gpios->ndescs; col++) {
|
||||
u32 bits_changed = gkb->last_key_state[col] ^ new_state[col];
|
||||
if (bits_changed == 0)
|
||||
continue;
|
||||
|
||||
for (row = 0; bits_changed; row++, bits_changed >>=1 ) {
|
||||
if (!(bits_changed & BIT(0)))
|
||||
continue;
|
||||
|
||||
code = MATRIX_SCAN_CODE(row, col, gkb->row_shift);
|
||||
input_event(input_dev, EV_MSC, MSC_SCAN, code);
|
||||
input_report_key(input_dev, keycodes[code],
|
||||
new_state[col] & (1 << row));
|
||||
}
|
||||
}
|
||||
input_sync(input_dev);
|
||||
|
||||
memcpy(gkb->last_key_state, new_state, sizeof(gkb->last_key_state));
|
||||
kfree(new_state);
|
||||
|
||||
/* Avoid missing key release events on quirky hardware */
|
||||
if (gkb->autorescan_ms && keymask) {
|
||||
queue_delayed_work(system_highpri_wq, &gkb->work,
|
||||
msecs_to_jiffies(gkb->autorescan_ms));
|
||||
return;
|
||||
}
|
||||
end:
|
||||
/* Enable IRQs again */
|
||||
mutex_lock(&gkb->lock);
|
||||
gkb->scan_pending = false;
|
||||
enable_row_irqs(gkb);
|
||||
mutex_unlock(&gkb->lock);
|
||||
}
|
||||
|
||||
static irqreturn_t gpio_keyboard_interrupt(int irq, void *id)
|
||||
{
|
||||
struct gpio_keyboard *gkb = id;
|
||||
|
||||
/*
|
||||
* See if another IRQ beaten us to it and scheduled the
|
||||
* scan already. In that case we should not try to
|
||||
* disable IRQs again.
|
||||
*/
|
||||
if (unlikely(gkb->scan_pending || gkb->stopped))
|
||||
goto out;
|
||||
|
||||
mutex_lock(&gkb->lock);
|
||||
|
||||
disable_row_irqs(gkb);
|
||||
gkb->scan_pending = true;
|
||||
mod_delayed_work(system_highpri_wq, &gkb->work,
|
||||
msecs_to_jiffies(gkb->debounce_ms));
|
||||
|
||||
out:
|
||||
mutex_unlock(&gkb->lock);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int gpio_keyboard_start(struct input_dev *dev)
|
||||
{
|
||||
struct gpio_keyboard *gkb = input_get_drvdata(dev);
|
||||
|
||||
gkb->stopped = false;
|
||||
|
||||
/*
|
||||
* Schedule an immediate key scan to capture current key state;
|
||||
* columns will be activated and IRQs be enabled after the scan.
|
||||
*/
|
||||
schedule_delayed_work(&gkb->work, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gpio_keyboard_stop(struct input_dev *dev)
|
||||
{
|
||||
struct gpio_keyboard *gkb = input_get_drvdata(dev);
|
||||
|
||||
mutex_lock(&gkb->lock);
|
||||
gkb->stopped = true;
|
||||
mutex_unlock(&gkb->lock);
|
||||
|
||||
flush_delayed_work(&gkb->work);
|
||||
/*
|
||||
* gpio_keyboard_scan() will leave IRQs enabled;
|
||||
* we should disable them now.
|
||||
*/
|
||||
disable_row_irqs(gkb);
|
||||
}
|
||||
|
||||
static void __maybe_unused gpio_keyboard_wakeup_en(struct gpio_keyboard *gkb)
|
||||
{
|
||||
int irq, i;
|
||||
|
||||
if (gkb->clustered_irq > 0) {
|
||||
if (enable_irq_wake(gkb->clustered_irq) == 0)
|
||||
gkb->gpio_all_disabled = true;
|
||||
} else {
|
||||
|
||||
for (i = 0; i < gkb->row_gpios->ndescs; i++) {
|
||||
if (!test_bit(i, gkb->disabled_gpios)) {
|
||||
irq = gpiod_to_irq(gkb->row_gpios->desc[i]);
|
||||
|
||||
if (enable_irq_wake(irq) == 0)
|
||||
__set_bit(i, gkb->disabled_gpios);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __maybe_unused gpio_keyboard_wakeup_dis(struct gpio_keyboard *gkb)
|
||||
{
|
||||
int irq, i;
|
||||
|
||||
if (gkb->clustered_irq > 0) {
|
||||
if (gkb->gpio_all_disabled) {
|
||||
disable_irq_wake(gkb->clustered_irq);
|
||||
gkb->gpio_all_disabled = false;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < gkb->row_gpios->ndescs; i++) {
|
||||
if (test_and_clear_bit(i, gkb->disabled_gpios)) {
|
||||
irq = gpiod_to_irq(gkb->row_gpios->desc[i]);
|
||||
disable_irq_wake(irq);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int __maybe_unused gpio_keyboard_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct gpio_keyboard *gkb = platform_get_drvdata(pdev);
|
||||
|
||||
gpio_keyboard_stop(gkb->input_dev);
|
||||
|
||||
if (device_may_wakeup(&pdev->dev))
|
||||
gpio_keyboard_wakeup_en(gkb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused gpio_keyboard_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct gpio_keyboard *gkb = platform_get_drvdata(pdev);
|
||||
|
||||
if (device_may_wakeup(&pdev->dev))
|
||||
gpio_keyboard_wakeup_dis(gkb);
|
||||
|
||||
gpio_keyboard_start(gkb->input_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static SIMPLE_DEV_PM_OPS(gpio_keyboard_pm_ops,
|
||||
gpio_keyboard_suspend, gpio_keyboard_resume);
|
||||
|
||||
static int gpio_keyboard_init_gpio(struct platform_device *pdev,
|
||||
struct gpio_keyboard *gkb)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
if (gkb->clustered_irq > 0) {
|
||||
ret = devm_request_threaded_irq(gkb->dev, gkb->clustered_irq,
|
||||
NULL, gpio_keyboard_interrupt,
|
||||
IRQF_ONESHOT, "gpio-keyboard", gkb);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"Cannot get IRQ %d\n", gkb->clustered_irq);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < gkb->row_gpios->ndescs; i++) {
|
||||
ret = devm_request_threaded_irq(
|
||||
gkb->dev,
|
||||
gpiod_to_irq(gkb->row_gpios->desc[i]),
|
||||
NULL, gpio_keyboard_interrupt,
|
||||
IRQF_TRIGGER_HIGH |
|
||||
IRQF_TRIGGER_LOW,
|
||||
"gpio-keyboard", gkb);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"Cannot get IRQ for gpio%d\n",
|
||||
desc_to_gpio(gkb->row_gpios->desc[i]));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* initialized as disabled - enabled by input->open */
|
||||
disable_row_irqs(gkb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_keyboard_parse_dt(struct gpio_keyboard *gkb)
|
||||
{
|
||||
struct device *dev = gkb->dev;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* Get as GPIOD_ASIS to use the configuration that comes from
|
||||
* device-tree. Anyway, in many cases the row is configured as
|
||||
* input, while the column is configured as output-high.
|
||||
*
|
||||
* This may vary depending on the hardware.
|
||||
*/
|
||||
gkb->row_gpios = devm_gpiod_get_array(dev, "row", GPIOD_ASIS);
|
||||
if (IS_ERR(gkb->row_gpios))
|
||||
return PTR_ERR(gkb->row_gpios);
|
||||
|
||||
gkb->col_gpios = devm_gpiod_get_array(dev, "col", GPIOD_ASIS);
|
||||
if (IS_ERR(gkb->col_gpios))
|
||||
return PTR_ERR(gkb->col_gpios);
|
||||
|
||||
/* All of these additional properties are optional */
|
||||
device_property_read_string(dev, "label", &gkb->input_dev->name);
|
||||
|
||||
if (device_property_read_bool(dev, "autorepeat"))
|
||||
__set_bit(EV_REP, gkb->input_dev->evbit);
|
||||
|
||||
gkb->drive_inactive_cols =
|
||||
device_property_read_bool(dev, "drive-inactive-cols");
|
||||
|
||||
rc = device_property_read_u32(dev, "autorescan-ms",
|
||||
&gkb->autorescan_ms);
|
||||
if (rc < 0)
|
||||
gkb->autorescan_ms = 0;
|
||||
|
||||
rc = device_property_read_u32(dev, "debounce-delay-ms",
|
||||
&gkb->debounce_ms);
|
||||
if (rc < 0)
|
||||
gkb->debounce_ms = 0;
|
||||
|
||||
rc = device_property_read_u32(dev, "col-scan-delay-us",
|
||||
&gkb->col_scan_us);
|
||||
if (rc < 0)
|
||||
gkb->col_scan_us = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_keyboard_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_keyboard *gkb;
|
||||
bool wake;
|
||||
int irq, ret;
|
||||
|
||||
gkb = devm_kmalloc(&pdev->dev, sizeof(*gkb), GFP_KERNEL);
|
||||
if (!gkb)
|
||||
return -ENOMEM;
|
||||
|
||||
gkb->dev = &pdev->dev;
|
||||
gkb->input_dev = devm_input_allocate_device(&pdev->dev);
|
||||
if (!gkb->input_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = gpio_keyboard_parse_dt(gkb);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
irq = platform_get_irq_optional(pdev, 0);
|
||||
gkb->clustered_irq = (irq > 0) ? irq : 0;
|
||||
gkb->row_shift = get_count_order(gkb->col_gpios->ndescs);
|
||||
gkb->stopped = true;
|
||||
INIT_DELAYED_WORK(&gkb->work, gpio_keyboard_scan);
|
||||
memset(gkb->last_key_state, 0, sizeof(gkb->last_key_state));
|
||||
mutex_init(&gkb->lock);
|
||||
|
||||
if (!gkb->input_dev->name)
|
||||
gkb->input_dev->name = pdev->name;
|
||||
gkb->input_dev->id.bustype = BUS_HOST;
|
||||
gkb->input_dev->dev.parent = &pdev->dev;
|
||||
gkb->input_dev->open = gpio_keyboard_start;
|
||||
gkb->input_dev->close = gpio_keyboard_stop;
|
||||
|
||||
ret = matrix_keypad_build_keymap(NULL, NULL,
|
||||
gkb->row_gpios->ndescs,
|
||||
gkb->col_gpios->ndescs,
|
||||
NULL, gkb->input_dev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to build keymap\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
input_set_capability(gkb->input_dev, EV_MSC, MSC_SCAN);
|
||||
input_set_drvdata(gkb->input_dev, gkb);
|
||||
|
||||
ret = gpio_keyboard_init_gpio(pdev, gkb);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = input_register_device(gkb->input_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
wake = device_property_read_bool(&pdev->dev, "wakeup-source");
|
||||
device_init_wakeup(&pdev->dev, wake);
|
||||
|
||||
platform_set_drvdata(pdev, gkb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_keyboard_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_keyboard *gkb = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
|
||||
if (gkb->clustered_irq > 0) {
|
||||
free_irq(gkb->clustered_irq, gkb);
|
||||
} else {
|
||||
for (i = 0; i < gkb->row_gpios->ndescs; i++)
|
||||
free_irq(gpiod_to_irq(gkb->row_gpios->desc[i]), gkb);
|
||||
}
|
||||
input_unregister_device(gkb->input_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id gpio_keyboard_dt_match[] = {
|
||||
{ .compatible = "gpio-fastmatrix-keyboard" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, gpio_keyboard_dt_match);
|
||||
|
||||
static struct platform_driver gpio_keyboard_driver = {
|
||||
.probe = gpio_keyboard_probe,
|
||||
.remove = gpio_keyboard_remove,
|
||||
.driver = {
|
||||
.name = "gpio-fastmatrix-keyboard",
|
||||
.pm = &gpio_keyboard_pm_ops,
|
||||
.of_match_table = gpio_keyboard_dt_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(gpio_keyboard_driver);
|
||||
|
||||
MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>");
|
||||
MODULE_DESCRIPTION("Fast GPIO driven keyboard/keypad matrix driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:gpio-fastmatrix-keyboard");
|
||||
|
|
@ -186,6 +186,18 @@ config INPUT_PMIC8XXX_PWRKEY
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called pmic8xxx-pwrkey.
|
||||
|
||||
config INPUT_QCOM_SPMI_HAPTICS
|
||||
tristate "Qualcomm SPMI HAPTICS"
|
||||
depends on ARCH_QCOM
|
||||
depends on SPMI
|
||||
select INPUT_FF_MEMLESS
|
||||
help
|
||||
This option enables support for the haptics found in pmi8998 and
|
||||
related PMICs. Based on the ff-memless interface.
|
||||
|
||||
To compile this driver as module, choose M here: the
|
||||
module will be called qcom_spmi_haptics.
|
||||
|
||||
config INPUT_SPARCSPKR
|
||||
tristate "SPARC Speaker support"
|
||||
depends on PCI && SPARC64
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY) += pmic8xxx-pwrkey.o
|
|||
obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
|
||||
obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o
|
||||
obj-$(CONFIG_INPUT_PWM_VIBRA) += pwm-vibra.o
|
||||
obj-$(CONFIG_INPUT_QCOM_SPMI_HAPTICS) += qcom-spmi-haptics.o
|
||||
obj-$(CONFIG_INPUT_RAVE_SP_PWRBUTTON) += rave-sp-pwrbutton.o
|
||||
obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o
|
||||
obj-$(CONFIG_INPUT_REGULATOR_HAPTIC) += regulator-haptic.o
|
||||
|
|
|
|||
977
drivers/input/misc/qcom-spmi-haptics.c
Normal file
977
drivers/input/misc/qcom-spmi-haptics.c
Normal file
|
|
@ -0,0 +1,977 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021, Caleb Connolly <caleb@connolly.tech>
|
||||
* Qualcomm QPMI haptics driver for pmi8998 and related PMICs.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/input/qcom,spmi-haptics.h>
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
|
||||
#define HAP_STATUS_1_REG 0x0A
|
||||
#define HAP_BUSY_BIT BIT(1)
|
||||
#define SC_FLAG_BIT BIT(3)
|
||||
#define AUTO_RES_ERROR_BIT BIT(4)
|
||||
|
||||
#define HAP_LRA_AUTO_RES_LO_REG 0x0B
|
||||
#define HAP_LRA_AUTO_RES_HI_REG 0x0C
|
||||
|
||||
#define HAP_EN_CTL_REG 0x46
|
||||
#define HAP_EN_BIT BIT(7)
|
||||
|
||||
#define HAP_EN_CTL2_REG 0x48
|
||||
#define BRAKE_EN_BIT BIT(0)
|
||||
|
||||
#define HAP_AUTO_RES_CTRL_REG 0x4B
|
||||
#define AUTO_RES_EN_BIT BIT(7)
|
||||
#define AUTO_RES_ERR_RECOVERY_BIT BIT(3)
|
||||
#define AUTO_RES_EN_FLAG_BIT BIT(0)
|
||||
|
||||
#define HAP_CFG1_REG 0x4C
|
||||
#define HAP_ACT_TYPE_MASK BIT(0)
|
||||
|
||||
#define HAP_CFG2_REG 0x4D
|
||||
#define HAP_LRA_RES_TYPE_MASK BIT(0)
|
||||
|
||||
#define HAP_SEL_REG 0x4E
|
||||
#define HAP_WF_SOURCE_MASK GENMASK(5, 4)
|
||||
#define HAP_WF_SOURCE_SHIFT 4
|
||||
|
||||
#define HAP_LRA_AUTO_RES_REG 0x4F
|
||||
#define LRA_AUTO_RES_MODE_MASK GENMASK(6, 4)
|
||||
#define LRA_AUTO_RES_MODE_SHIFT 4
|
||||
#define LRA_HIGH_Z_MASK GENMASK(3, 2)
|
||||
#define LRA_HIGH_Z_SHIFT 2
|
||||
#define LRA_RES_CAL_MASK GENMASK(1, 0)
|
||||
#define HAP_RES_CAL_PERIOD_MIN 4
|
||||
#define HAP_RES_CAL_PERIOD_MAX 32
|
||||
|
||||
#define HAP_VMAX_CFG_REG 0x51
|
||||
#define HAP_VMAX_OVD_BIT BIT(6)
|
||||
#define HAP_VMAX_MASK GENMASK(5, 1)
|
||||
#define HAP_VMAX_SHIFT 1
|
||||
|
||||
#define HAP_ILIM_CFG_REG 0x52
|
||||
#define HAP_ILIM_SEL_MASK BIT(0)
|
||||
#define HAP_ILIM_400_MA 0
|
||||
#define HAP_ILIM_800_MA 1
|
||||
|
||||
#define HAP_SC_DEB_REG 0x53
|
||||
#define HAP_SC_DEB_MASK GENMASK(2, 0)
|
||||
#define HAP_SC_DEB_CYCLES_MIN 0
|
||||
#define HAP_DEF_SC_DEB_CYCLES 8
|
||||
#define HAP_SC_DEB_CYCLES_MAX 32
|
||||
|
||||
#define HAP_RATE_CFG1_REG 0x54
|
||||
#define HAP_RATE_CFG1_MASK GENMASK(7, 0)
|
||||
#define HAP_RATE_CFG2_SHIFT 8
|
||||
|
||||
#define HAP_RATE_CFG2_REG 0x55
|
||||
#define HAP_RATE_CFG2_MASK GENMASK(3, 0)
|
||||
|
||||
#define HAP_SC_CLR_REG 0x59
|
||||
#define SC_CLR_BIT BIT(0)
|
||||
|
||||
#define HAP_BRAKE_REG 0x5C
|
||||
#define HAP_BRAKE_PAT_MASK 0x3
|
||||
|
||||
#define HAP_WF_REPEAT_REG 0x5E
|
||||
#define WF_REPEAT_MASK GENMASK(6, 4)
|
||||
#define WF_REPEAT_SHIFT 4
|
||||
#define WF_REPEAT_MIN 1
|
||||
#define WF_REPEAT_MAX 128
|
||||
#define WF_S_REPEAT_MASK GENMASK(1, 0)
|
||||
#define WF_S_REPEAT_MIN 1
|
||||
#define WF_S_REPEAT_MAX 8
|
||||
|
||||
#define HAP_WF_S1_REG 0x60
|
||||
#define HAP_WF_SIGN_BIT BIT(7)
|
||||
#define HAP_WF_OVD_BIT BIT(6)
|
||||
#define HAP_WF_SAMP_MAX GENMASK(5, 1)
|
||||
#define HAP_WF_SAMPLE_LEN 8
|
||||
|
||||
#define HAP_PLAY_REG 0x70
|
||||
#define HAP_PLAY_BIT BIT(7)
|
||||
#define HAP_PAUSE_BIT BIT(0)
|
||||
|
||||
#define HAP_SEC_ACCESS_REG 0xD0
|
||||
#define HAP_SEC_ACCESS_UNLOCK 0xA5
|
||||
|
||||
#define HAP_TEST2_REG 0xE3
|
||||
|
||||
|
||||
#define HAP_VMAX_MIN_MV 116
|
||||
#define HAP_VMAX_MAX_MV 3596
|
||||
#define HAP_VMAX_MAX_MV_STRONG 3596
|
||||
|
||||
#define HAP_WAVE_PLAY_RATE_MIN_US 0
|
||||
#define HAP_WAVE_PLAY_RATE_MAX_US 20475
|
||||
#define HAP_WAVE_PLAY_TIME_MAX_MS 15000
|
||||
|
||||
#define AUTO_RES_ERR_POLL_TIME_NS (20 * NSEC_PER_MSEC)
|
||||
#define HAPTICS_BACK_EMF_DELAY_US 20000
|
||||
|
||||
#define HAP_BRAKE_PAT_LEN 4
|
||||
#define HAP_WAVE_SAMP_LEN 8
|
||||
#define NUM_WF_SET 4
|
||||
#define HAP_WAVE_SAMP_SET_LEN (HAP_WAVE_SAMP_LEN * NUM_WF_SET)
|
||||
#define HAP_RATE_CFG_STEP_US 5
|
||||
|
||||
#define SC_MAX_COUNT 5
|
||||
#define SC_COUNT_RST_DELAY_US 1000000
|
||||
|
||||
enum hap_play_control {
|
||||
HAP_STOP,
|
||||
HAP_PAUSE,
|
||||
HAP_PLAY,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct spmi_haptics - struct for spmi haptics data.
|
||||
*
|
||||
* @dev: Our device parent.
|
||||
* @regmap: Register map for the hardware block.
|
||||
* @haptics_input_dev: The input device used to receive events.
|
||||
* @work: Work struct to play effects.
|
||||
* @base: Base address of the regmap.
|
||||
* @active: Atomic value used to track if haptics are currently playing.
|
||||
* @play_irq: Fired to load the next wave pattern.
|
||||
* @sc_irq: Short circuit irq.
|
||||
* @last_sc_time: Time since the short circuit IRQ last fired.
|
||||
* @sc_count: Number of times the short circuit IRQ has fired in this interval.
|
||||
* @actuator_type: The type of actuator in use.
|
||||
* @wave_shape: The shape of the waves to use (sine or square).
|
||||
* @play_mode: The play mode to use (direct, buffer, pwm, audio).
|
||||
* @magnitude: The strength we should be playing at.
|
||||
* @vmax: Max voltage to use when playing.
|
||||
* @current_limit: The current limit for this hardware (400mA or 800mA).
|
||||
* @play_wave_rate: The wave rate to use for this hardware.
|
||||
* @wave_samp: The array of wave samples to write for buffer mode.
|
||||
* @brake_pat: The pattern to apply when braking.
|
||||
* @play_lock: Lock to be held when updating the hardware state.
|
||||
*/
|
||||
struct spmi_haptics {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct input_dev *haptics_input_dev;
|
||||
struct work_struct work;
|
||||
u32 base;
|
||||
|
||||
atomic_t active;
|
||||
|
||||
int play_irq;
|
||||
int sc_irq;
|
||||
ktime_t last_sc_time;
|
||||
u8 sc_count;
|
||||
|
||||
u8 actuator_type;
|
||||
u8 wave_shape;
|
||||
u8 play_mode;
|
||||
int magnitude;
|
||||
u32 vmax;
|
||||
u32 current_limit;
|
||||
u32 play_wave_rate;
|
||||
|
||||
u32 wave_samp[HAP_WAVE_SAMP_SET_LEN];
|
||||
u8 brake_pat[HAP_BRAKE_PAT_LEN];
|
||||
|
||||
struct mutex play_lock;
|
||||
};
|
||||
|
||||
static inline bool is_secure_addr(u16 addr)
|
||||
{
|
||||
return (addr & 0xFF) > 0xD0;
|
||||
}
|
||||
|
||||
static int spmi_haptics_read(struct spmi_haptics *haptics,
|
||||
u16 addr, u8 *val, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regmap_bulk_read(haptics->regmap, addr, val, len);
|
||||
if (ret < 0)
|
||||
dev_err(haptics->dev, "Error reading address: 0x%x, ret %d\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int spmi_haptics_write(struct spmi_haptics *haptics,
|
||||
u16 addr, u8 *val, int len)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
if (is_secure_addr(addr)) {
|
||||
for (i = 0; i < len; i++) {
|
||||
dev_dbg(haptics->dev, "%s: unlocking for addr: 0x%x, val: 0x%x", __func__,
|
||||
addr, val[i]);
|
||||
ret = regmap_write(haptics->regmap,
|
||||
haptics->base + HAP_SEC_ACCESS_REG, HAP_SEC_ACCESS_UNLOCK);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error writing unlock code, ret %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_write(haptics->regmap, addr + i, val[i]);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error writing address 0x%x, ret %d\n",
|
||||
addr + i, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (len > 1)
|
||||
ret = regmap_bulk_write(haptics->regmap, addr, val, len);
|
||||
else
|
||||
ret = regmap_write(haptics->regmap, addr, *val);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
dev_err(haptics->dev, "%s: Error writing address: 0x%x, ret %d\n",
|
||||
__func__, addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_masked(struct spmi_haptics *haptics,
|
||||
u16 addr, u8 mask, u8 val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (is_secure_addr(addr)) {
|
||||
ret = regmap_write(haptics->regmap,
|
||||
haptics->base + HAP_SEC_ACCESS_REG, HAP_SEC_ACCESS_UNLOCK);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error writing unlock code - ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(haptics->regmap, addr, mask, val);
|
||||
if (ret < 0)
|
||||
dev_err(haptics->dev, "Error writing address: 0x%x - ret %d\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool is_haptics_idle(struct spmi_haptics *haptics)
|
||||
{
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
if (haptics->play_mode == HAP_PLAY_DIRECT ||
|
||||
haptics->play_mode == HAP_PLAY_PWM)
|
||||
return true;
|
||||
|
||||
ret = spmi_haptics_read(haptics, haptics->base + HAP_STATUS_1_REG, &val, 1);
|
||||
if (ret < 0 || (val & HAP_BUSY_BIT))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int spmi_haptics_module_enable(struct spmi_haptics *haptics, bool enable)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
dev_dbg(haptics->dev, "Setting module enable: %d", enable);
|
||||
|
||||
val = enable ? HAP_EN_BIT : 0;
|
||||
return spmi_haptics_write(haptics, haptics->base + HAP_EN_CTL_REG, &val, 1);
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_vmax(struct spmi_haptics *haptics)
|
||||
{
|
||||
u8 val = 0;
|
||||
u32 vmax_mv = haptics->vmax;
|
||||
|
||||
vmax_mv = clamp_t(u32, vmax_mv, HAP_VMAX_MIN_MV, HAP_VMAX_MAX_MV);
|
||||
|
||||
dev_dbg(haptics->dev, "Setting vmax to: %d", vmax_mv);
|
||||
|
||||
val = DIV_ROUND_CLOSEST(vmax_mv, HAP_VMAX_MIN_MV);
|
||||
val = FIELD_PREP(HAP_VMAX_MASK, val);
|
||||
|
||||
// TODO: pm660 can enable overdrive here
|
||||
|
||||
return spmi_haptics_write_masked(haptics, haptics->base + HAP_VMAX_CFG_REG,
|
||||
HAP_VMAX_MASK | HAP_WF_OVD_BIT, val);
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_current_limit(struct spmi_haptics *haptics)
|
||||
{
|
||||
haptics->current_limit = clamp_t(u32, haptics->current_limit,
|
||||
HAP_ILIM_400_MA, HAP_ILIM_800_MA);
|
||||
|
||||
dev_dbg(haptics->dev, "Setting current_limit to: 0x%x", haptics->current_limit);
|
||||
|
||||
return spmi_haptics_write_masked(haptics, haptics->base + HAP_ILIM_CFG_REG,
|
||||
HAP_ILIM_SEL_MASK, haptics->current_limit);
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_play_mode(struct spmi_haptics *haptics)
|
||||
{
|
||||
u8 val = 0;
|
||||
|
||||
if (!is_haptics_idle(haptics))
|
||||
return -EBUSY;
|
||||
|
||||
dev_dbg(haptics->dev, "Setting play_mode to: 0x%x", haptics->play_mode);
|
||||
|
||||
val = FIELD_PREP(HAP_WF_SOURCE_MASK, haptics->play_mode);
|
||||
return spmi_haptics_write_masked(haptics, haptics->base + HAP_SEL_REG,
|
||||
HAP_WF_SOURCE_MASK, val);
|
||||
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_play_rate(struct spmi_haptics *haptics, u16 play_rate)
|
||||
{
|
||||
u8 val[2];
|
||||
|
||||
dev_dbg(haptics->dev, "Setting play_rate to: %d", play_rate);
|
||||
|
||||
val[0] = FIELD_PREP(HAP_RATE_CFG1_MASK, play_rate);
|
||||
val[1] = FIELD_PREP(HAP_RATE_CFG2_MASK, play_rate >> HAP_RATE_CFG2_SHIFT);
|
||||
return spmi_haptics_write(haptics, haptics->base + HAP_RATE_CFG1_REG, val, 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* spmi_haptics_set_auto_res() - Auto resonance
|
||||
* allows the haptics to automatically adjust the
|
||||
* speed of the oscillation in order to maintain
|
||||
* the resonant frequency.
|
||||
*/
|
||||
static int spmi_haptics_set_auto_res(struct spmi_haptics *haptics, bool enable)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
// LRAs are the only type to support auto res
|
||||
if (haptics->actuator_type != HAP_TYPE_LRA)
|
||||
return 0;
|
||||
|
||||
val = enable ? AUTO_RES_EN_BIT : 0;
|
||||
|
||||
return spmi_haptics_write_masked(haptics, haptics->base + HAP_TEST2_REG,
|
||||
AUTO_RES_EN_BIT, val);
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_brake(struct spmi_haptics *haptics)
|
||||
{
|
||||
int ret, i;
|
||||
u8 val;
|
||||
|
||||
dev_dbg(haptics->dev, "Configuring brake pattern");
|
||||
|
||||
ret = spmi_haptics_write_masked(haptics, haptics->base + HAP_EN_CTL2_REG,
|
||||
BRAKE_EN_BIT, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (i = HAP_BRAKE_PAT_LEN - 1, val = 0; i >= 0; i--) {
|
||||
u8 p = haptics->brake_pat[i] & HAP_BRAKE_PAT_MASK;
|
||||
|
||||
val |= p << (i * 2);
|
||||
}
|
||||
|
||||
return spmi_haptics_write(haptics, haptics->base + HAP_BRAKE_REG, &val, 1);
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_buffer_config(struct spmi_haptics *haptics)
|
||||
{
|
||||
u8 buf[HAP_WAVE_SAMP_LEN];
|
||||
int i;
|
||||
|
||||
dev_dbg(haptics->dev, "Writing buffer config");
|
||||
|
||||
for (i = 0; i < HAP_WAVE_SAMP_LEN; i++)
|
||||
buf[i] = haptics->wave_samp[i];
|
||||
|
||||
return spmi_haptics_write(haptics, haptics->base + HAP_WF_S1_REG, buf,
|
||||
HAP_WAVE_SAMP_LEN);
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_wave_repeat(struct spmi_haptics *haptics)
|
||||
{
|
||||
u8 val, mask;
|
||||
|
||||
/* The number of times to repeat each wave */
|
||||
mask = WF_REPEAT_MASK | WF_S_REPEAT_MASK;
|
||||
val = FIELD_PREP(WF_REPEAT_MASK, 0) |
|
||||
FIELD_PREP(WF_S_REPEAT_MASK, 0);
|
||||
|
||||
return spmi_haptics_write_masked(haptics, haptics->base + HAP_WF_REPEAT_REG,
|
||||
mask, val);
|
||||
}
|
||||
|
||||
static int spmi_haptics_write_play_control(struct spmi_haptics *haptics,
|
||||
enum hap_play_control ctrl)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
switch (ctrl) {
|
||||
case HAP_STOP:
|
||||
val = 0;
|
||||
break;
|
||||
case HAP_PAUSE:
|
||||
val = HAP_PAUSE_BIT;
|
||||
break;
|
||||
case HAP_PLAY:
|
||||
val = HAP_PLAY_BIT;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_dbg(haptics->dev, "haptics play ctrl: %d\n", ctrl);
|
||||
return spmi_haptics_write(haptics, haptics->base + HAP_PLAY_REG, &val, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This IRQ is fired to tell us to load the next wave sample set.
|
||||
* As we only currently support a single sample set, it's unused.
|
||||
*/
|
||||
static irqreturn_t spmi_haptics_play_irq_handler(int irq, void *data)
|
||||
{
|
||||
struct spmi_haptics *haptics = data;
|
||||
|
||||
dev_dbg(haptics->dev, "play_irq triggered");
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* spmi_haptics_sc_irq_handler() - short circuit irq handler
|
||||
* Fires every ~50ms whilst the haptics are active.
|
||||
* If the SC_FLAG_BIT is set then that means there isn't a short circuit
|
||||
* and we just need to clear the IRQ to indicate that the device should
|
||||
* keep vibrating.
|
||||
*
|
||||
* Otherwise, it means a short circuit situation has occurred.
|
||||
*
|
||||
* @irq: irq number
|
||||
* @data: haptics data
|
||||
* Returns: IRQ_HANDLED
|
||||
*/
|
||||
static irqreturn_t spmi_haptics_sc_irq_handler(int irq, void *data)
|
||||
{
|
||||
struct spmi_haptics *haptics = data;
|
||||
int ret;
|
||||
u8 val;
|
||||
s64 sc_delta_time_us;
|
||||
ktime_t temp;
|
||||
|
||||
ret = spmi_haptics_read(haptics, haptics->base + HAP_STATUS_1_REG, &val, 1);
|
||||
if (ret < 0)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
if (!(val & SC_FLAG_BIT)) {
|
||||
haptics->sc_count = 0;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
temp = ktime_get();
|
||||
sc_delta_time_us = ktime_us_delta(temp, haptics->last_sc_time);
|
||||
haptics->last_sc_time = temp;
|
||||
|
||||
if (sc_delta_time_us > SC_COUNT_RST_DELAY_US)
|
||||
haptics->sc_count = 0;
|
||||
else
|
||||
haptics->sc_count++;
|
||||
|
||||
// Clear the interrupt flag
|
||||
val = SC_CLR_BIT;
|
||||
ret = spmi_haptics_write(haptics, haptics->base + HAP_SC_CLR_REG, &val, 1);
|
||||
if (ret < 0)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
if (haptics->sc_count > SC_MAX_COUNT) {
|
||||
dev_err(haptics->dev, "Short circuit persists, disabling haptics\n");
|
||||
ret = spmi_haptics_module_enable(haptics, false);
|
||||
if (ret < 0)
|
||||
dev_err(haptics->dev, "Error disabling module, rc=%d\n", ret);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* spmi_haptics_init() - Initialise haptics hardware for use
|
||||
* @haptics: haptics device
|
||||
* Returns: 0 on success, < 0 on error
|
||||
*/
|
||||
static int spmi_haptics_init(struct spmi_haptics *haptics)
|
||||
{
|
||||
int ret;
|
||||
u8 val, mask;
|
||||
u16 play_rate;
|
||||
|
||||
ret = spmi_haptics_write_masked(haptics, haptics->base + HAP_CFG1_REG,
|
||||
HAP_ACT_TYPE_MASK, haptics->actuator_type);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Configure auto resonance
|
||||
* see spmi_haptics_lra_auto_res_config downstream
|
||||
* This is greatly simplified.
|
||||
*/
|
||||
val = FIELD_PREP(LRA_RES_CAL_MASK, ilog2(32 / HAP_RES_CAL_PERIOD_MIN)) |
|
||||
FIELD_PREP(LRA_AUTO_RES_MODE_MASK, HAP_AUTO_RES_ZXD_EOP) |
|
||||
FIELD_PREP(LRA_HIGH_Z_MASK, 1);
|
||||
|
||||
mask = LRA_AUTO_RES_MODE_MASK | LRA_HIGH_Z_MASK | LRA_RES_CAL_MASK;
|
||||
|
||||
ret = spmi_haptics_write_masked(haptics, haptics->base + HAP_LRA_AUTO_RES_REG,
|
||||
mask, val);
|
||||
|
||||
/* Configure the PLAY MODE register */
|
||||
ret = spmi_haptics_write_play_mode(haptics);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = spmi_haptics_write_vmax(haptics);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Configure the ILIM register */
|
||||
ret = spmi_haptics_write_current_limit(haptics);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
// Configure the debounce for short-circuit detection.
|
||||
ret = spmi_haptics_write_masked(haptics, haptics->base + HAP_SC_DEB_REG,
|
||||
HAP_SC_DEB_MASK, HAP_SC_DEB_CYCLES_MAX);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
// write the wave shape
|
||||
ret = spmi_haptics_write_masked(haptics, haptics->base + HAP_CFG2_REG,
|
||||
HAP_LRA_RES_TYPE_MASK, haptics->wave_shape);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
play_rate = haptics->play_wave_rate / HAP_RATE_CFG_STEP_US;
|
||||
|
||||
/*
|
||||
* Configure RATE_CFG1 and RATE_CFG2 registers.
|
||||
* Note: For ERM these registers act as play rate and
|
||||
* for LRA these represent resonance period
|
||||
*/
|
||||
ret = spmi_haptics_write_play_rate(haptics, play_rate);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = spmi_haptics_write_brake(haptics);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (haptics->play_mode == HAP_PLAY_BUFFER) {
|
||||
ret = spmi_haptics_write_wave_repeat(haptics);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = spmi_haptics_write_buffer_config(haptics);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(haptics->dev, "%s: Requesting play IRQ, irq: %d", __func__,
|
||||
haptics->play_irq);
|
||||
ret = devm_request_threaded_irq(haptics->dev, haptics->play_irq,
|
||||
NULL, spmi_haptics_play_irq_handler, IRQF_ONESHOT,
|
||||
"haptics_play_irq", haptics);
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Unable to request play IRQ ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* use play_irq only for buffer mode */
|
||||
if (haptics->play_mode != HAP_PLAY_BUFFER)
|
||||
disable_irq(haptics->play_irq);
|
||||
|
||||
dev_dbg(haptics->dev, "%s: Requesting play IRQ, irq: %d", __func__,
|
||||
haptics->play_irq);
|
||||
ret = devm_request_threaded_irq(haptics->dev, haptics->sc_irq,
|
||||
NULL, spmi_haptics_sc_irq_handler, IRQF_ONESHOT,
|
||||
"haptics_sc_irq", haptics);
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Unable to request sc IRQ ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* spmi_haptics_enable - handler to start/stop vibration
|
||||
* @haptics: pointer to haptics struct
|
||||
* Returns: 0 on success, < 0 on failure
|
||||
*/
|
||||
static int spmi_haptics_enable(struct spmi_haptics *haptics)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&haptics->play_lock);
|
||||
if (haptics->sc_count > SC_MAX_COUNT) {
|
||||
dev_err(haptics->dev, "Can't play while in short circuit");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
ret = spmi_haptics_set_auto_res(haptics, false);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error disabling auto_res, ret=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = spmi_haptics_module_enable(haptics, true);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error enabling module, ret=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = spmi_haptics_write_play_control(haptics, HAP_PLAY);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error enabling play, ret=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = spmi_haptics_set_auto_res(haptics, true);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error enabling auto_res, ret=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&haptics->play_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* spmi_haptics_enable - handler to start/stop vibration
|
||||
* @haptics: pointer to haptics struct
|
||||
* Returns: 0 on success, < 0 on failure
|
||||
*/
|
||||
static int spmi_haptics_disable(struct spmi_haptics *haptics)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&haptics->play_lock);
|
||||
|
||||
ret = spmi_haptics_write_play_control(haptics, HAP_STOP);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error disabling play, ret=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = spmi_haptics_module_enable(haptics, false);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Error disabling module, ret=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&haptics->play_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Threaded function to update the haptics state.
|
||||
*/
|
||||
static void spmi_haptics_work(struct work_struct *work)
|
||||
{
|
||||
struct spmi_haptics *haptics = container_of(work, struct spmi_haptics, work);
|
||||
|
||||
int ret;
|
||||
bool enable;
|
||||
|
||||
enable = atomic_read(&haptics->active);
|
||||
dev_dbg(haptics->dev, "%s: state: %d\n", __func__, enable);
|
||||
|
||||
if (enable)
|
||||
ret = spmi_haptics_enable(haptics);
|
||||
else
|
||||
ret = spmi_haptics_disable(haptics);
|
||||
if (ret < 0)
|
||||
dev_err(haptics->dev, "Error setting haptics, ret=%d", ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* spmi_haptics_close - callback for input device close
|
||||
* @dev: input device pointer
|
||||
*
|
||||
* Turns off the vibrator.
|
||||
*/
|
||||
static void spmi_haptics_close(struct input_dev *dev)
|
||||
{
|
||||
struct spmi_haptics *haptics = input_get_drvdata(dev);
|
||||
|
||||
cancel_work_sync(&haptics->work);
|
||||
if (atomic_read(&haptics->active)) {
|
||||
atomic_set(&haptics->active, 0);
|
||||
schedule_work(&haptics->work);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* spmi_haptics_play_effect - play haptics effects
|
||||
* @dev: input device pointer
|
||||
* @data: data of effect
|
||||
* @effect: effect to play
|
||||
*/
|
||||
static int spmi_haptics_play_effect(struct input_dev *dev, void *data,
|
||||
struct ff_effect *effect)
|
||||
{
|
||||
struct spmi_haptics *haptics = input_get_drvdata(dev);
|
||||
|
||||
dev_dbg(haptics->dev, "%s: Rumbling with strong: %d and weak: %d", __func__,
|
||||
effect->u.rumble.strong_magnitude, effect->u.rumble.weak_magnitude);
|
||||
|
||||
haptics->magnitude = effect->u.rumble.strong_magnitude >> 8;
|
||||
if (!haptics->magnitude)
|
||||
haptics->magnitude = effect->u.rumble.weak_magnitude >> 10;
|
||||
|
||||
if (!haptics->magnitude) {
|
||||
atomic_set(&haptics->active, 0);
|
||||
goto end;
|
||||
}
|
||||
|
||||
atomic_set(&haptics->active, 1);
|
||||
|
||||
haptics->vmax = ((HAP_VMAX_MAX_MV - HAP_VMAX_MIN_MV) * haptics->magnitude) / 100 +
|
||||
HAP_VMAX_MIN_MV;
|
||||
|
||||
dev_dbg(haptics->dev, "%s: magnitude: %d, vmax: %d", __func__,
|
||||
haptics->magnitude, haptics->vmax);
|
||||
|
||||
spmi_haptics_write_vmax(haptics);
|
||||
|
||||
end:
|
||||
schedule_work(&haptics->work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spmi_haptics_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct spmi_haptics *haptics;
|
||||
struct device_node *node;
|
||||
struct input_dev *input_dev;
|
||||
int ret;
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
haptics = devm_kzalloc(&pdev->dev, sizeof(*haptics), GFP_KERNEL);
|
||||
if (!haptics)
|
||||
return -ENOMEM;
|
||||
|
||||
haptics->regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
||||
if (!haptics->regmap)
|
||||
return -ENODEV;
|
||||
|
||||
node = pdev->dev.of_node;
|
||||
|
||||
haptics->dev = &pdev->dev;
|
||||
|
||||
ret = of_property_read_u32(node, "reg", &haptics->base);
|
||||
if (ret < 0) {
|
||||
dev_err(haptics->dev, "Couldn't find reg in node = %s ret = %d\n",
|
||||
node->full_name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
haptics->play_irq = platform_get_irq_byname(pdev, "play");
|
||||
if (haptics->play_irq < 0) {
|
||||
dev_err(&pdev->dev, "Unable to get play irq\n");
|
||||
ret = haptics->play_irq;
|
||||
goto register_fail;
|
||||
}
|
||||
|
||||
haptics->sc_irq = platform_get_irq_byname(pdev, "short");
|
||||
if (haptics->sc_irq < 0) {
|
||||
dev_err(&pdev->dev, "Unable to get sc irq\n");
|
||||
ret = haptics->sc_irq;
|
||||
goto register_fail;
|
||||
}
|
||||
|
||||
// We only support LRAs for now
|
||||
haptics->actuator_type = HAP_TYPE_LRA;
|
||||
ret = of_property_read_u32(node, "qcom,actuator-type", &val);
|
||||
if (!ret) {
|
||||
if (val != HAP_TYPE_LRA) {
|
||||
dev_err(&pdev->dev, "qcom,actuator-type (%d) isn't supported\n", val);
|
||||
ret = -EINVAL;
|
||||
goto register_fail;
|
||||
}
|
||||
haptics->actuator_type = val;
|
||||
}
|
||||
|
||||
// Only buffer mode is currently supported
|
||||
haptics->play_mode = HAP_PLAY_BUFFER;
|
||||
ret = of_property_read_u32(node, "qcom,play-mode", &val);
|
||||
if (!ret) {
|
||||
if (val != HAP_PLAY_BUFFER) {
|
||||
dev_err(&pdev->dev, "qcom,play-mode (%d) isn't supported\n", val);
|
||||
ret = -EINVAL;
|
||||
goto register_fail;
|
||||
}
|
||||
haptics->play_mode = val;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(node, "qcom,wave-play-rate-us", &val);
|
||||
if (!ret) {
|
||||
haptics->play_wave_rate = val;
|
||||
} else if (ret != -EINVAL) {
|
||||
dev_err(haptics->dev, "Unable to read play rate ret=%d\n", ret);
|
||||
goto register_fail;
|
||||
}
|
||||
|
||||
haptics->play_wave_rate =
|
||||
clamp_t(u32, haptics->play_wave_rate,
|
||||
HAP_WAVE_PLAY_RATE_MIN_US, HAP_WAVE_PLAY_RATE_MAX_US);
|
||||
|
||||
haptics->wave_shape = HAP_WAVE_SINE;
|
||||
ret = of_property_read_u32(node, "qcom,wave-shape", &val);
|
||||
if (!ret) {
|
||||
if (val != HAP_WAVE_SINE && val != HAP_WAVE_SQUARE) {
|
||||
dev_err(&pdev->dev, "qcom,wave-shape is invalid: %d\n", val);
|
||||
ret = -EINVAL;
|
||||
goto register_fail;
|
||||
}
|
||||
haptics->wave_shape = val;
|
||||
}
|
||||
|
||||
haptics->brake_pat[0] = 0x3;
|
||||
haptics->brake_pat[1] = 0x3;
|
||||
haptics->brake_pat[2] = 0x2;
|
||||
haptics->brake_pat[3] = 0x1;
|
||||
|
||||
ret = of_property_read_u8_array(node, "qcom,brake-pattern", haptics->brake_pat, 4);
|
||||
if (ret < 0 && ret != -EINVAL) {
|
||||
dev_err(&pdev->dev, "qcom,brake-pattern is invalid, ret = %d\n", ret);
|
||||
goto register_fail;
|
||||
}
|
||||
|
||||
haptics->current_limit = HAP_ILIM_400_MA;
|
||||
|
||||
for (i = 0; i < HAP_WAVE_SAMP_LEN; i++)
|
||||
haptics->wave_samp[i] = HAP_WF_SAMP_MAX;
|
||||
|
||||
ret = spmi_haptics_init(haptics);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Error initialising haptics, ret=%d\n",
|
||||
ret);
|
||||
goto register_fail;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, haptics);
|
||||
|
||||
input_dev = devm_input_allocate_device(&pdev->dev);
|
||||
if (!input_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_WORK(&haptics->work, spmi_haptics_work);
|
||||
haptics->haptics_input_dev = input_dev;
|
||||
|
||||
input_dev->name = "spmi_haptics";
|
||||
input_dev->id.version = 1;
|
||||
input_dev->close = spmi_haptics_close;
|
||||
input_set_drvdata(input_dev, haptics);
|
||||
// Figure out how to make this FF_PERIODIC
|
||||
input_set_capability(haptics->haptics_input_dev, EV_FF, FF_RUMBLE);
|
||||
|
||||
ret = input_ff_create_memless(input_dev, NULL,
|
||||
spmi_haptics_play_effect);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"couldn't register vibrator as FF device\n");
|
||||
goto register_fail;
|
||||
}
|
||||
|
||||
ret = input_register_device(input_dev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "couldn't register input device\n");
|
||||
goto register_fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
register_fail:
|
||||
cancel_work_sync(&haptics->work);
|
||||
mutex_destroy(&haptics->play_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __maybe_unused spmi_haptics_suspend(struct device *dev)
|
||||
{
|
||||
struct spmi_haptics *haptics = dev_get_drvdata(dev);
|
||||
|
||||
cancel_work_sync(&haptics->work);
|
||||
spmi_haptics_disable(haptics);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(spmi_haptics_pm_ops, spmi_haptics_suspend, NULL);
|
||||
|
||||
static int spmi_haptics_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spmi_haptics *haptics = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
cancel_work_sync(&haptics->work);
|
||||
mutex_destroy(&haptics->play_lock);
|
||||
input_unregister_device(haptics->haptics_input_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spmi_haptics_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct spmi_haptics *haptics = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
cancel_work_sync(&haptics->work);
|
||||
|
||||
spmi_haptics_disable(haptics);
|
||||
}
|
||||
|
||||
static const struct of_device_id spmi_haptics_match_table[] = {
|
||||
{ .compatible = "qcom,spmi-haptics" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, spmi_haptics_match_table);
|
||||
|
||||
static struct platform_driver spmi_haptics_driver = {
|
||||
.probe = spmi_haptics_probe,
|
||||
.remove = spmi_haptics_remove,
|
||||
.shutdown = spmi_haptics_shutdown,
|
||||
.driver = {
|
||||
.name = "spmi-haptics",
|
||||
.pm = &spmi_haptics_pm_ops,
|
||||
.of_match_table = spmi_haptics_match_table,
|
||||
},
|
||||
};
|
||||
module_platform_driver(spmi_haptics_driver);
|
||||
|
||||
MODULE_DESCRIPTION("spmi haptics driver using ff-memless framework");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Caleb Connolly <caleb@connolly.tech>");
|
||||
|
|
@ -82,6 +82,14 @@ config RMI4_F12
|
|||
touchpads. For sensors that support relative pointing, F12 also
|
||||
provides mouse input.
|
||||
|
||||
config RMI4_F1A
|
||||
bool "RMI4 Function 1A (Simple capacitive buttons)"
|
||||
depends on OF
|
||||
help
|
||||
Say Y here if you want to add support for RMI4 function 1A.
|
||||
|
||||
Function 1A provides GPIO capacitive button support for RMI4 devices.
|
||||
|
||||
config RMI4_F30
|
||||
bool "RMI4 Function 30 (GPIO LED)"
|
||||
help
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
|
|||
rmi_core-$(CONFIG_RMI4_F03) += rmi_f03.o
|
||||
rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
|
||||
rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
|
||||
rmi_core-$(CONFIG_RMI4_F1A) += rmi_f1a.o
|
||||
rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
|
||||
rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o rmi_f34v7.o
|
||||
rmi_core-$(CONFIG_RMI4_F3A) += rmi_f3a.o
|
||||
|
|
|
|||
|
|
@ -360,6 +360,9 @@ static struct rmi_function_handler *fn_handlers[] = {
|
|||
#ifdef CONFIG_RMI4_F12
|
||||
&rmi_f12_handler,
|
||||
#endif
|
||||
#ifdef CONFIG_RMI4_F1A
|
||||
&rmi_f1a_handler,
|
||||
#endif
|
||||
#ifdef CONFIG_RMI4_F30
|
||||
&rmi_f30_handler,
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ extern struct rmi_function_handler rmi_f01_handler;
|
|||
extern struct rmi_function_handler rmi_f03_handler;
|
||||
extern struct rmi_function_handler rmi_f11_handler;
|
||||
extern struct rmi_function_handler rmi_f12_handler;
|
||||
extern struct rmi_function_handler rmi_f1a_handler;
|
||||
extern struct rmi_function_handler rmi_f30_handler;
|
||||
extern struct rmi_function_handler rmi_f34_handler;
|
||||
extern struct rmi_function_handler rmi_f3a_handler;
|
||||
|
|
|
|||
190
drivers/input/rmi4/rmi_f1a.c
Normal file
190
drivers/input/rmi4/rmi_f1a.c
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
// FIXME: Too much stuff is hardcoded in currently!
|
||||
#include <linux/input.h>
|
||||
#include <linux/rmi.h>
|
||||
#include <linux/of.h>
|
||||
#include "rmi_driver.h"
|
||||
|
||||
/* Query 1 */
|
||||
//#define F1A_BUTTONS_COUNT 0b00011111 /* BIT(1) */
|
||||
|
||||
#define MAX_NAME_LEN 256
|
||||
#define F1A_MAX_BUTTONS 8
|
||||
|
||||
struct f1a_data {
|
||||
struct rmi_function *fn;
|
||||
|
||||
unsigned char button_count;
|
||||
u32 button_map[F1A_MAX_BUTTONS];
|
||||
struct input_dev *input;
|
||||
char input_name[MAX_NAME_LEN];
|
||||
char input_phys[MAX_NAME_LEN];
|
||||
u8 button_data_buffer;
|
||||
};
|
||||
|
||||
static int rmi_f1a_initialize(struct f1a_data *f1a)
|
||||
{
|
||||
struct rmi_function *fn = f1a->fn;
|
||||
struct device *dev = &fn->dev;
|
||||
//u8 query[2];
|
||||
int error;
|
||||
|
||||
/*error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr, query, 2);
|
||||
if (error) {
|
||||
dev_err(dev, "Failed to read query register (%d).\n", error);
|
||||
return error;
|
||||
}
|
||||
printk("%s: query0: 0x%x, query1: 0x%x\n", __func__, query[0], query[1]);*/
|
||||
|
||||
error = of_property_read_variable_u32_array(dev_of_node(dev),
|
||||
"syna,codes", f1a->button_map, 1, F1A_MAX_BUTTONS);
|
||||
if (error < 0) {
|
||||
dev_err(dev, "Failed to parse syna,codes from OF device tree (%d).\n", error);
|
||||
return error;
|
||||
}
|
||||
// FIXME: button_count = query[1] & F1A_BUTTONS_COUNT;
|
||||
f1a->button_count = 0;
|
||||
for (f1a->button_count = 0; f1a->button_count < F1A_MAX_BUTTONS; f1a->button_count++)
|
||||
if (f1a->button_map[f1a->button_count] == 0)
|
||||
break;
|
||||
rmi_dbg(RMI_DEBUG_FN, dev, "%s: %d button codes defined\n", __func__, f1a->button_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rmi_f1a_register_device(struct f1a_data *f1a)
|
||||
{
|
||||
struct rmi_function *fn = f1a->fn;
|
||||
struct device *dev = &fn->dev;
|
||||
struct rmi_device *rmi_dev = fn->rmi_dev;
|
||||
struct input_dev *input_dev;
|
||||
int i, rc;
|
||||
|
||||
input_dev = input_allocate_device();
|
||||
if (!input_dev) {
|
||||
dev_err(dev, "Failed to allocate input device.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
f1a->input = input_dev;
|
||||
snprintf(f1a->input_name, MAX_NAME_LEN, "%s.fn%02x",
|
||||
dev_name(&rmi_dev->dev), fn->fd.function_number);
|
||||
input_dev->name = f1a->input_name;
|
||||
snprintf(f1a->input_phys, MAX_NAME_LEN, "%s/input0", input_dev->name);
|
||||
input_dev->phys = f1a->input_phys;
|
||||
input_dev->dev.parent = &rmi_dev->dev;
|
||||
input_set_drvdata(input_dev, f1a);
|
||||
|
||||
/* set up any input events */
|
||||
set_bit(EV_SYN, input_dev->evbit);
|
||||
set_bit(EV_KEY, input_dev->evbit);
|
||||
|
||||
/* manage button map using input subsystem */
|
||||
input_dev->keycode = f1a->button_map;
|
||||
input_dev->keycodesize = sizeof(f1a->button_map); /* f1a->button_count */
|
||||
input_dev->keycodemax = f1a->button_count;
|
||||
|
||||
/* set bits for each button */
|
||||
for (i = 0; i < f1a->button_count; i++) {
|
||||
set_bit(f1a->button_map[i], input_dev->keybit);
|
||||
input_set_capability(input_dev, EV_KEY, f1a->button_map[i]);
|
||||
}
|
||||
|
||||
rc = input_register_device(input_dev);
|
||||
if (rc < 0) {
|
||||
dev_err(dev, "Failed to register input device.\n");
|
||||
goto error_free_device;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_free_device:
|
||||
input_free_device(input_dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int rmi_f1a_probe(struct rmi_function *fn)
|
||||
{
|
||||
struct device *dev = &fn->dev;
|
||||
struct f1a_data *f1a;
|
||||
int error;
|
||||
|
||||
rmi_dbg(RMI_DEBUG_FN, dev, "%s\n", __func__);
|
||||
|
||||
if (!fn->dev.of_node) {
|
||||
/*
|
||||
* Some quirky devices (e.g. OnePlus 5T) report supporting F1A
|
||||
* (Simple capacitive buttons) despite not having the hardware,
|
||||
* so in case there isn't an associated device-tree node present
|
||||
* just pretend we probed successfully.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
f1a = devm_kzalloc(dev, sizeof(struct f1a_data), GFP_KERNEL);
|
||||
if (!f1a)
|
||||
return -ENOMEM;
|
||||
|
||||
f1a->fn = fn;
|
||||
|
||||
error = rmi_f1a_initialize(f1a);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
error = rmi_f1a_register_device(f1a);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
dev_set_drvdata(dev, f1a);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rmi_f1a_config(struct rmi_function *fn)
|
||||
{
|
||||
fn->rmi_dev->driver->set_irq_bits(fn->rmi_dev, fn->irq_mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t rmi_f1a_attention(int irq, void *ctx)
|
||||
{
|
||||
struct rmi_function *fn = ctx;
|
||||
struct device *dev = &fn->dev;
|
||||
struct rmi_device *rmi_dev = fn->rmi_dev;
|
||||
struct f1a_data *f1a = dev_get_drvdata(dev);
|
||||
int error, button;
|
||||
|
||||
// TODO: use rmi_read_block() to accomodate up to 8 buttons?
|
||||
error = rmi_read(rmi_dev, fn->fd.data_base_addr, &(f1a->button_data_buffer));
|
||||
if (error < 0) {
|
||||
dev_err(dev, "Failed to read button data registers (%d).\n", error);
|
||||
return error;
|
||||
}
|
||||
/*rmi_dbg(RMI_DEBUG_FN, dev, "%s: button_data=0x%x\n", __func__, f1a->button_data_buffer);*/
|
||||
|
||||
/* generate events for buttons that change state */
|
||||
// TODO: Implement button_data_buffer as array + button_reg = button / 8
|
||||
for (button = 0; button < f1a->button_count; button++) {
|
||||
int button_shift;
|
||||
bool button_status;
|
||||
/* bit shift to get button's status */
|
||||
button_shift = button % 8;
|
||||
button_status = ((f1a->button_data_buffer >> button_shift) & 0x01) != 0;
|
||||
|
||||
rmi_dbg(RMI_DEBUG_FN, dev, "button %d (code %d) -> %d\n",
|
||||
button, f1a->button_map[button], button_status);
|
||||
/* generate an event here */
|
||||
input_report_key(f1a->input, f1a->button_map[button], button_status);
|
||||
}
|
||||
input_sync(f1a->input); /* sync after groups of events */
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
struct rmi_function_handler rmi_f1a_handler = {
|
||||
.driver = {
|
||||
.name = "rmi4_f1a",
|
||||
},
|
||||
.func = 0x1a,
|
||||
.probe = rmi_f1a_probe,
|
||||
.config = rmi_f1a_config,
|
||||
.attention = rmi_f1a_attention,
|
||||
};
|
||||
|
|
@ -44,6 +44,15 @@ config INTERCONNECT_QCOM_MSM8996
|
|||
This is a driver for the Qualcomm Network-on-Chip on msm8996-based
|
||||
platforms.
|
||||
|
||||
config INTERCONNECT_QCOM_MSM8998
|
||||
tristate "Qualcomm MSM8998 interconnect driver"
|
||||
depends on INTERCONNECT_QCOM
|
||||
depends on QCOM_SMD_RPM
|
||||
select INTERCONNECT_QCOM_SMD_RPM
|
||||
help
|
||||
This is a driver for the Qualcomm Network-on-Chip on msm8998-based
|
||||
platforms.
|
||||
|
||||
config INTERCONNECT_QCOM_OSM_L3
|
||||
tristate "Qualcomm OSM L3 interconnect driver"
|
||||
depends on INTERCONNECT_QCOM || COMPILE_TEST
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ qnoc-msm8916-objs := msm8916.o
|
|||
qnoc-msm8939-objs := msm8939.o
|
||||
qnoc-msm8974-objs := msm8974.o
|
||||
qnoc-msm8996-objs := msm8996.o
|
||||
qnoc-msm8998-objs := msm8998.o
|
||||
icc-osm-l3-objs := osm-l3.o
|
||||
qnoc-qcm2290-objs := qcm2290.o
|
||||
qnoc-qcs404-objs := qcs404.o
|
||||
|
|
@ -26,6 +27,7 @@ obj-$(CONFIG_INTERCONNECT_QCOM_MSM8916) += qnoc-msm8916.o
|
|||
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8939) += qnoc-msm8939.o
|
||||
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8974) += qnoc-msm8974.o
|
||||
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8996) += qnoc-msm8996.o
|
||||
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8998) += qnoc-msm8998.o
|
||||
obj-$(CONFIG_INTERCONNECT_QCOM_OSM_L3) += icc-osm-l3.o
|
||||
obj-$(CONFIG_INTERCONNECT_QCOM_QCM2290) += qnoc-qcm2290.o
|
||||
obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o
|
||||
|
|
|
|||
981
drivers/interconnect/qcom/msm8998.c
Normal file
981
drivers/interconnect/qcom/msm8998.c
Normal file
|
|
@ -0,0 +1,981 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Qualcomm MSM8998 Network-on-Chip (NoC) QoS driver
|
||||
* Copyright (c) 2020, AngeloGioacchino Del Regno
|
||||
* <angelogioacchino.delregno@somainline.org>
|
||||
* Copyright (C) 2020, Konrad Dybcio <konrad.dybcio@somainline.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <dt-bindings/interconnect/qcom,msm8998.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/interconnect-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "smd-rpm.h"
|
||||
|
||||
#define RPM_BUS_MASTER_REQ 0x73616d62
|
||||
#define RPM_BUS_SLAVE_REQ 0x766c7362
|
||||
|
||||
/* BIMC QoS */
|
||||
#define M_BKE_REG_BASE(n) (0x300 + (0x4000 * n))
|
||||
#define M_BKE_EN_ADDR(n) (M_BKE_REG_BASE(n))
|
||||
#define M_BKE_HEALTH_CFG_ADDR(i, n) (M_BKE_REG_BASE(n) + 0x40 + (0x4 * i))
|
||||
|
||||
#define M_BKE_HEALTH_CFG_LIMITCMDS_MASK 0x80000000
|
||||
#define M_BKE_HEALTH_CFG_AREQPRIO_MASK 0x300
|
||||
#define M_BKE_HEALTH_CFG_PRIOLVL_MASK 0x3
|
||||
#define M_BKE_HEALTH_CFG_AREQPRIO_SHIFT 0x8
|
||||
#define M_BKE_HEALTH_CFG_LIMITCMDS_SHIFT 0x1f
|
||||
|
||||
#define M_BKE_EN_EN_BMASK 0x1
|
||||
|
||||
/* Valid for both NoC and BIMC */
|
||||
#define NOC_QOS_MODE_FIXED 0x0
|
||||
#define NOC_QOS_MODE_LIMITER 0x1
|
||||
#define NOC_QOS_MODE_BYPASS 0x2
|
||||
|
||||
/* NoC QoS */
|
||||
#define NOC_PERM_MODE_FIXED 1
|
||||
#define NOC_PERM_MODE_BYPASS (1 << NOC_QOS_MODE_BYPASS)
|
||||
|
||||
#define NOC_QOS_PRIORITYn_ADDR(n) (0x8 + (n * 0x1000))
|
||||
#define NOC_QOS_PRIORITY_MASK 0xf
|
||||
#define NOC_QOS_PRIORITY_P1_SHIFT 0x2
|
||||
#define NOC_QOS_PRIORITY_P0_SHIFT 0x3
|
||||
|
||||
#define NOC_QOS_MODEn_ADDR(n) (0xc + (n * 0x1000))
|
||||
#define NOC_QOS_MODEn_MASK 0x3
|
||||
|
||||
enum {
|
||||
MSM8998_MASTER_IPA = 1,
|
||||
MSM8998_MASTER_CNOC_A2NOC,
|
||||
MSM8998_MASTER_SDCC_2,
|
||||
MSM8998_MASTER_SDCC_4,
|
||||
MSM8998_MASTER_BLSP_1,
|
||||
MSM8998_MASTER_BLSP_2,
|
||||
MSM8998_MASTER_UFS,
|
||||
MSM8998_MASTER_USB_HS,
|
||||
MSM8998_MASTER_USB3,
|
||||
MSM8998_MASTER_CRYPTO_C0,
|
||||
MSM8998_MASTER_GNOC_BIMC,
|
||||
MSM8998_MASTER_OXILI,
|
||||
MSM8998_MASTER_MNOC_BIMC,
|
||||
MSM8998_MASTER_SNOC_BIMC,
|
||||
MSM8998_MASTER_PIMEM,
|
||||
MSM8998_MASTER_SNOC_CNOC,
|
||||
MSM8998_MASTER_QDSS_DAP,
|
||||
MSM8998_MASTER_APPS_PROC,
|
||||
MSM8998_MASTER_CNOC_MNOC_MMSS_CFG,
|
||||
MSM8998_MASTER_CNOC_MNOC_CFG,
|
||||
MSM8998_MASTER_CPP,
|
||||
MSM8998_MASTER_JPEG,
|
||||
MSM8998_MASTER_MDP_P0,
|
||||
MSM8998_MASTER_MDP_P1,
|
||||
MSM8998_MASTER_VENUS,
|
||||
MSM8998_MASTER_VFE,
|
||||
MSM8998_MASTER_QDSS_ETR,
|
||||
MSM8998_MASTER_QDSS_BAM,
|
||||
MSM8998_MASTER_SNOC_CFG,
|
||||
MSM8998_MASTER_BIMC_SNOC,
|
||||
MSM8998_MASTER_A1NOC_SNOC,
|
||||
MSM8998_MASTER_A2NOC_SNOC,
|
||||
MSM8998_MASTER_GNOC_SNOC,
|
||||
MSM8998_MASTER_PCIE_0,
|
||||
MSM8998_MASTER_A2NOC_TSIF,
|
||||
MSM8998_MASTER_CRVIRT_A2NOC,
|
||||
MSM8998_MASTER_ROTATOR,
|
||||
MSM8998_MASTER_VENUS_VMEM,
|
||||
MSM8998_MASTER_HMSS,
|
||||
MSM8998_MASTER_BIMC_SNOC_0,
|
||||
MSM8998_MASTER_BIMC_SNOC_1,
|
||||
|
||||
MSM8998_SLAVE_A1NOC_SNOC,
|
||||
MSM8998_SLAVE_A2NOC_SNOC,
|
||||
MSM8998_SLAVE_EBI,
|
||||
MSM8998_SLAVE_HMSS_L3,
|
||||
MSM8998_SLAVE_CNOC_A2NOC,
|
||||
MSM8998_SLAVE_MPM,
|
||||
MSM8998_SLAVE_PMIC_ARB,
|
||||
MSM8998_SLAVE_TLMM_NORTH,
|
||||
MSM8998_SLAVE_TCSR,
|
||||
MSM8998_SLAVE_PIMEM_CFG,
|
||||
MSM8998_SLAVE_IMEM_CFG,
|
||||
MSM8998_SLAVE_MESSAGE_RAM,
|
||||
MSM8998_SLAVE_GLM,
|
||||
MSM8998_SLAVE_BIMC_CFG,
|
||||
MSM8998_SLAVE_PRNG,
|
||||
MSM8998_SLAVE_SPDM,
|
||||
MSM8998_SLAVE_QDSS_CFG,
|
||||
MSM8998_SLAVE_CNOC_MNOC_CFG,
|
||||
MSM8998_SLAVE_SNOC_CFG,
|
||||
MSM8998_SLAVE_QM_CFG,
|
||||
MSM8998_SLAVE_CLK_CTL,
|
||||
MSM8998_SLAVE_MSS_CFG,
|
||||
MSM8998_SLAVE_UFS_CFG,
|
||||
MSM8998_SLAVE_A2NOC_CFG,
|
||||
MSM8998_SLAVE_A2NOC_SMMU_CFG,
|
||||
MSM8998_SLAVE_GPUSS_CFG,
|
||||
MSM8998_SLAVE_AHB2PHY,
|
||||
MSM8998_SLAVE_BLSP_1,
|
||||
MSM8998_SLAVE_SDCC_2,
|
||||
MSM8998_SLAVE_SDCC_4,
|
||||
MSM8998_SLAVE_BLSP_2,
|
||||
MSM8998_SLAVE_PDM,
|
||||
MSM8998_SLAVE_CNOC_MNOC_MMSS_CFG,
|
||||
MSM8998_SLAVE_USB_HS,
|
||||
MSM8998_SLAVE_USB3_0,
|
||||
MSM8998_SLAVE_SRVC_CNOC,
|
||||
MSM8998_SLAVE_GNOC_BIMC,
|
||||
MSM8998_SLAVE_GNOC_SNOC,
|
||||
MSM8998_SLAVE_CAMERA_CFG,
|
||||
MSM8998_SLAVE_CAMERA_THROTTLE_CFG,
|
||||
MSM8998_SLAVE_MISC_CFG,
|
||||
MSM8998_SLAVE_VENUS_THROTTLE_CFG,
|
||||
MSM8998_SLAVE_VENUS_CFG,
|
||||
MSM8998_SLAVE_MMSS_CLK_XPU_CFG,
|
||||
MSM8998_SLAVE_MMSS_CLK_CFG,
|
||||
MSM8998_SLAVE_MNOC_MPU_CFG,
|
||||
MSM8998_SLAVE_DISPLAY_CFG,
|
||||
MSM8998_SLAVE_CSI_PHY_CFG,
|
||||
MSM8998_SLAVE_DISPLAY_THROTTLE_CFG,
|
||||
MSM8998_SLAVE_SMMU_CFG,
|
||||
MSM8998_SLAVE_MNOC_BIMC,
|
||||
MSM8998_SLAVE_SRVC_MNOC,
|
||||
MSM8998_SLAVE_HMSS,
|
||||
MSM8998_SLAVE_LPASS,
|
||||
MSM8998_SLAVE_WLAN,
|
||||
MSM8998_SLAVE_CDSP,
|
||||
MSM8998_SLAVE_IPA,
|
||||
MSM8998_SLAVE_SNOC_BIMC,
|
||||
MSM8998_SLAVE_SNOC_CNOC,
|
||||
MSM8998_SLAVE_IMEM,
|
||||
MSM8998_SLAVE_PIMEM,
|
||||
MSM8998_SLAVE_QDSS_STM,
|
||||
MSM8998_SLAVE_SRVC_SNOC,
|
||||
MSM8998_SLAVE_BIMC_SNOC_0,
|
||||
MSM8998_SLAVE_BIMC_SNOC_1,
|
||||
MSM8998_SLAVE_SSC_CFG,
|
||||
MSM8998_SLAVE_SKL,
|
||||
MSM8998_SLAVE_TLMM_WEST,
|
||||
MSM8998_SLAVE_A1NOC_CFG,
|
||||
MSM8998_SLAVE_A1NOC_SMMU_CFG,
|
||||
MSM8998_SLAVE_TSIF,
|
||||
MSM8998_SLAVE_TLMM_EAST,
|
||||
MSM8998_SLAVE_CRVIRT_A2NOC,
|
||||
MSM8998_SLAVE_VMEM_CFG,
|
||||
MSM8998_SLAVE_VMEM,
|
||||
MSM8998_SLAVE_PCIE_0,
|
||||
};
|
||||
|
||||
#define to_qcom_provider(_provider) \
|
||||
container_of(_provider, struct qcom_icc_provider, provider)
|
||||
|
||||
static const struct clk_bulk_data bus_clocks[] = {
|
||||
{ .id = "bus" },
|
||||
{ .id = "bus_a" },
|
||||
};
|
||||
|
||||
static const struct clk_bulk_data bus_mm_clocks[] = {
|
||||
{ .id = "bus" },
|
||||
{ .id = "bus_a" },
|
||||
{ .id = "iface" },
|
||||
};
|
||||
|
||||
/**
|
||||
* struct qcom_icc_provider - Qualcomm specific interconnect provider
|
||||
* @provider: generic interconnect provider
|
||||
* @bus_clks: the clk_bulk_data table of bus clocks
|
||||
* @num_clks: the total number of clk_bulk_data entries
|
||||
* @is_bimc_node: indicates whether to use bimc specific setting
|
||||
* @mmio: NoC base iospace
|
||||
*/
|
||||
struct qcom_icc_provider {
|
||||
struct icc_provider provider;
|
||||
struct clk_bulk_data *bus_clks;
|
||||
int num_clks;
|
||||
bool is_bimc_node;
|
||||
struct regmap *regmap;
|
||||
void __iomem *mmio;
|
||||
};
|
||||
|
||||
#define MSM8998_MAX_LINKS 38
|
||||
|
||||
/**
|
||||
* struct qcom_icc_qos - Qualcomm specific interconnect QoS parameters
|
||||
* @areq_prio: node requests priority
|
||||
* @prio_level: priority level for bus communication
|
||||
* @limit_commands: activate/deactivate limiter mode during runtime
|
||||
* @ap_owned: indicates if the node is owned by the AP or by the RPM
|
||||
* @qos_mode: default qos mode for this node
|
||||
* @qos_port: qos port number for finding qos registers of this node
|
||||
*/
|
||||
struct qcom_icc_qos {
|
||||
u32 areq_prio;
|
||||
u32 prio_level;
|
||||
bool limit_commands;
|
||||
bool ap_owned;
|
||||
int qos_mode;
|
||||
int qos_port;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct qcom_icc_node - Qualcomm specific interconnect nodes
|
||||
* @name: the node name used in debugfs
|
||||
* @id: a unique node identifier
|
||||
* @links: an array of nodes where we can go next while traversing
|
||||
* @num_links: the total number of @links
|
||||
* @buswidth: width of the interconnect between a node and the bus (bytes)
|
||||
* @mas_rpm_id: RPM id for devices that are bus masters
|
||||
* @slv_rpm_id: RPM id for devices that are bus slaves
|
||||
* @qos: NoC QoS setting parameters
|
||||
* @rate: current bus clock rate in Hz
|
||||
*/
|
||||
struct qcom_icc_node {
|
||||
unsigned char *name;
|
||||
u16 id;
|
||||
u16 links[MSM8998_MAX_LINKS];
|
||||
u16 num_links;
|
||||
u16 buswidth;
|
||||
int mas_rpm_id;
|
||||
int slv_rpm_id;
|
||||
struct qcom_icc_qos qos;
|
||||
u64 rate;
|
||||
};
|
||||
|
||||
struct qcom_icc_desc {
|
||||
struct qcom_icc_node **nodes;
|
||||
size_t num_nodes;
|
||||
const struct regmap_config *regmap_cfg;
|
||||
};
|
||||
|
||||
#define DEFINE_QNODE(_name, _id, _buswidth, _mas_rpm_id, _slv_rpm_id, \
|
||||
_ap_owned, _qos_mode, _qos_prio, _qos_port, ...) \
|
||||
static struct qcom_icc_node _name = { \
|
||||
.name = #_name, \
|
||||
.id = _id, \
|
||||
.buswidth = _buswidth, \
|
||||
.mas_rpm_id = _mas_rpm_id, \
|
||||
.slv_rpm_id = _slv_rpm_id, \
|
||||
.qos.ap_owned = _ap_owned, \
|
||||
.qos.qos_mode = _qos_mode, \
|
||||
.qos.areq_prio = _qos_prio, \
|
||||
.qos.prio_level = _qos_prio, \
|
||||
.qos.qos_port = _qos_port, \
|
||||
.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })), \
|
||||
.links = { __VA_ARGS__ }, \
|
||||
}
|
||||
|
||||
/* masters */
|
||||
DEFINE_QNODE(mas_pcie_0, MSM8998_MASTER_PCIE_0, 16, 45, -1, true, NOC_QOS_MODE_FIXED, 1, 1, MSM8998_SLAVE_A1NOC_SNOC);
|
||||
DEFINE_QNODE(mas_usb3, MSM8998_MASTER_USB3, 16, 32, -1, true, NOC_QOS_MODE_FIXED, 1, 2, MSM8998_SLAVE_A1NOC_SNOC);
|
||||
DEFINE_QNODE(mas_ufs, MSM8998_MASTER_UFS, 16, 68, -1, true, NOC_QOS_MODE_FIXED, 1, 2, MSM8998_SLAVE_A1NOC_SNOC);
|
||||
DEFINE_QNODE(mas_blsp_2, MSM8998_MASTER_BLSP_2, 16, 39, -1, false, NOC_QOS_MODE_FIXED, 0, 4, MSM8998_SLAVE_A1NOC_SNOC);
|
||||
DEFINE_QNODE(mas_cnoc_a2noc, MSM8998_MASTER_CNOC_A2NOC, 8, 146, -1, true, -1, 0, -1, MSM8998_SLAVE_A2NOC_SNOC);
|
||||
DEFINE_QNODE(mas_ipa, MSM8998_MASTER_IPA, 8, 59, -1, true, NOC_QOS_MODE_FIXED, 1, 1, MSM8998_SLAVE_A2NOC_SNOC);
|
||||
DEFINE_QNODE(mas_sdcc_2, MSM8998_MASTER_SDCC_2, 8, 35, -1, false, NOC_QOS_MODE_FIXED, 0, 6, MSM8998_SLAVE_A2NOC_SNOC);
|
||||
DEFINE_QNODE(mas_sdcc_4, MSM8998_MASTER_SDCC_4, 8, 36, -1, false, NOC_QOS_MODE_FIXED, 0, 7, MSM8998_SLAVE_A2NOC_SNOC);
|
||||
DEFINE_QNODE(mas_tsif, MSM8998_MASTER_A2NOC_TSIF, 4, 37, -1, true, -1, 0, -1, MSM8998_SLAVE_A2NOC_SNOC);
|
||||
DEFINE_QNODE(mas_blsp_1, MSM8998_MASTER_BLSP_1, 16, 41, -1, false, NOC_QOS_MODE_FIXED, 0, 8, MSM8998_SLAVE_A2NOC_SNOC);
|
||||
DEFINE_QNODE(mas_crvirt_a2noc, MSM8998_MASTER_CRVIRT_A2NOC, 8, 145, -1, false, NOC_QOS_MODE_FIXED, 0, 9, MSM8998_SLAVE_A2NOC_SNOC);
|
||||
DEFINE_QNODE(mas_gnoc_bimc, MSM8998_MASTER_GNOC_BIMC, 8, 144, -1, true, NOC_QOS_MODE_FIXED, 0, 0, MSM8998_SLAVE_EBI, MSM8998_SLAVE_BIMC_SNOC_0);
|
||||
DEFINE_QNODE(mas_oxili, MSM8998_MASTER_OXILI, 8, 6, -1, true, NOC_QOS_MODE_BYPASS, 0, 1, MSM8998_SLAVE_BIMC_SNOC_1, MSM8998_SLAVE_HMSS_L3, MSM8998_SLAVE_EBI, MSM8998_SLAVE_BIMC_SNOC_0);
|
||||
DEFINE_QNODE(mas_mnoc_bimc, MSM8998_MASTER_MNOC_BIMC, 8, 2, -1, true, NOC_QOS_MODE_BYPASS, 0, 2, MSM8998_SLAVE_BIMC_SNOC_1, MSM8998_SLAVE_HMSS_L3, MSM8998_SLAVE_EBI, MSM8998_SLAVE_BIMC_SNOC_0);
|
||||
DEFINE_QNODE(mas_snoc_bimc, MSM8998_MASTER_SNOC_BIMC, 8, 3, -1, false, NOC_QOS_MODE_BYPASS, 0, 3, MSM8998_SLAVE_HMSS_L3, MSM8998_SLAVE_EBI);
|
||||
DEFINE_QNODE(mas_snoc_cnoc, MSM8998_MASTER_SNOC_CNOC, 8, 52, -1, true, -1, 0, -1, MSM8998_SLAVE_SKL, MSM8998_SLAVE_BLSP_2, MSM8998_SLAVE_MESSAGE_RAM, MSM8998_SLAVE_TLMM_WEST, MSM8998_SLAVE_TSIF, MSM8998_SLAVE_MPM, MSM8998_SLAVE_BIMC_CFG, MSM8998_SLAVE_TLMM_EAST, MSM8998_SLAVE_SPDM, MSM8998_SLAVE_PIMEM_CFG, MSM8998_SLAVE_A1NOC_SMMU_CFG, MSM8998_SLAVE_BLSP_1, MSM8998_SLAVE_CLK_CTL, MSM8998_SLAVE_PRNG, MSM8998_SLAVE_USB3_0, MSM8998_SLAVE_QDSS_CFG, MSM8998_SLAVE_QM_CFG, MSM8998_SLAVE_A2NOC_CFG, MSM8998_SLAVE_PMIC_ARB, MSM8998_SLAVE_UFS_CFG, MSM8998_SLAVE_SRVC_CNOC, MSM8998_SLAVE_AHB2PHY, MSM8998_SLAVE_IPA, MSM8998_SLAVE_GLM, MSM8998_SLAVE_SNOC_CFG, MSM8998_SLAVE_SSC_CFG, MSM8998_SLAVE_SDCC_2, MSM8998_SLAVE_SDCC_4, MSM8998_SLAVE_PDM, MSM8998_SLAVE_CNOC_MNOC_MMSS_CFG, MSM8998_SLAVE_CNOC_MNOC_CFG, MSM8998_SLAVE_MSS_CFG, MSM8998_SLAVE_IMEM_CFG, MSM8998_SLAVE_A1NOC_CFG, MSM8998_SLAVE_GPUSS_CFG, MSM8998_SLAVE_TCSR, MSM8998_SLAVE_TLMM_NORTH);
|
||||
DEFINE_QNODE(mas_qdss_dap, MSM8998_MASTER_QDSS_DAP, 8, 49, -1, true, -1, 0, -1, MSM8998_SLAVE_SKL, MSM8998_SLAVE_BLSP_2, MSM8998_SLAVE_MESSAGE_RAM, MSM8998_SLAVE_TLMM_WEST, MSM8998_SLAVE_TSIF, MSM8998_SLAVE_MPM, MSM8998_SLAVE_BIMC_CFG, MSM8998_SLAVE_TLMM_EAST, MSM8998_SLAVE_SPDM, MSM8998_SLAVE_PIMEM_CFG, MSM8998_SLAVE_A1NOC_SMMU_CFG, MSM8998_SLAVE_BLSP_1, MSM8998_SLAVE_CLK_CTL, MSM8998_SLAVE_PRNG, MSM8998_SLAVE_USB3_0, MSM8998_SLAVE_QDSS_CFG, MSM8998_SLAVE_QM_CFG, MSM8998_SLAVE_A2NOC_CFG, MSM8998_SLAVE_PMIC_ARB, MSM8998_SLAVE_UFS_CFG, MSM8998_SLAVE_SRVC_CNOC, MSM8998_SLAVE_AHB2PHY, MSM8998_SLAVE_IPA, MSM8998_SLAVE_GLM, MSM8998_SLAVE_SNOC_CFG, MSM8998_SLAVE_SDCC_2, MSM8998_SLAVE_SDCC_4, MSM8998_SLAVE_PDM, MSM8998_SLAVE_CNOC_MNOC_MMSS_CFG, MSM8998_SLAVE_CNOC_MNOC_CFG, MSM8998_SLAVE_MSS_CFG, MSM8998_SLAVE_IMEM_CFG, MSM8998_SLAVE_A1NOC_CFG, MSM8998_SLAVE_GPUSS_CFG, MSM8998_SLAVE_SSC_CFG, MSM8998_SLAVE_TCSR, MSM8998_SLAVE_TLMM_NORTH, MSM8998_SLAVE_CNOC_A2NOC);
|
||||
DEFINE_QNODE(mas_crypto, MSM8998_MASTER_CRYPTO_C0, 650, 23, -1, false, -1, 0, -1, MSM8998_MASTER_CRVIRT_A2NOC);
|
||||
DEFINE_QNODE(mas_apss_proc, MSM8998_MASTER_APPS_PROC, 32, 0, -1, true, -1, 0, -1, MSM8998_SLAVE_GNOC_BIMC);
|
||||
DEFINE_QNODE(mas_cnoc_mnoc_mmss_cfg, MSM8998_MASTER_CNOC_MNOC_MMSS_CFG, 8, 4, -1, true, -1, 0, -1, MSM8998_SLAVE_CAMERA_THROTTLE_CFG, MSM8998_SLAVE_VENUS_CFG, MSM8998_SLAVE_MISC_CFG, MSM8998_SLAVE_CAMERA_CFG, MSM8998_SLAVE_DISPLAY_THROTTLE_CFG, MSM8998_SLAVE_VENUS_THROTTLE_CFG, MSM8998_SLAVE_DISPLAY_CFG, MSM8998_SLAVE_MMSS_CLK_CFG, MSM8998_SLAVE_VMEM_CFG, MSM8998_SLAVE_MMSS_CLK_XPU_CFG, MSM8998_SLAVE_SMMU_CFG);
|
||||
DEFINE_QNODE(mas_cnoc_mnoc_cfg, MSM8998_MASTER_CNOC_MNOC_CFG, 8, 5, -1, true, -1, 0, -1, MSM8998_SLAVE_SRVC_MNOC);
|
||||
DEFINE_QNODE(mas_cpp, MSM8998_MASTER_CPP, 32, 115, -1, true, NOC_QOS_MODE_BYPASS, 0, 5, MSM8998_SLAVE_MNOC_BIMC);
|
||||
DEFINE_QNODE(mas_jpeg, MSM8998_MASTER_JPEG, 32, 7, -1, true, NOC_QOS_MODE_BYPASS, 0, 7, MSM8998_SLAVE_MNOC_BIMC);
|
||||
DEFINE_QNODE(mas_mdp_p0, MSM8998_MASTER_MDP_P0, 32, 8, -1, true, NOC_QOS_MODE_BYPASS, 0, 1, MSM8998_SLAVE_MNOC_BIMC); /* vrail-comp???? */
|
||||
DEFINE_QNODE(mas_mdp_p1, MSM8998_MASTER_MDP_P1, 32, 61, -1, true, NOC_QOS_MODE_BYPASS, 0, 2, MSM8998_SLAVE_MNOC_BIMC); /* vrail-comp??? */
|
||||
DEFINE_QNODE(mas_rotator, MSM8998_MASTER_ROTATOR, 32, 120, -1, true, NOC_QOS_MODE_BYPASS, 0, 0, MSM8998_SLAVE_MNOC_BIMC);
|
||||
DEFINE_QNODE(mas_venus, MSM8998_MASTER_VENUS, 32, 9, -1, true, NOC_QOS_MODE_BYPASS, 0, 3, MSM8998_SLAVE_MNOC_BIMC);
|
||||
DEFINE_QNODE(mas_vfe, MSM8998_MASTER_VFE, 32, 11, -1, true, NOC_QOS_MODE_BYPASS, 0, 6, MSM8998_SLAVE_MNOC_BIMC);
|
||||
DEFINE_QNODE(mas_venus_vmem, MSM8998_MASTER_VENUS_VMEM, 32, 121, -1, true, -1, 0, -1, MSM8998_SLAVE_VMEM);
|
||||
DEFINE_QNODE(mas_hmss, MSM8998_MASTER_HMSS, 16, 118, -1, true, NOC_QOS_MODE_FIXED, 1, 3, MSM8998_SLAVE_PIMEM, MSM8998_SLAVE_IMEM, MSM8998_SLAVE_SNOC_BIMC);
|
||||
DEFINE_QNODE(mas_qdss_bam, MSM8998_MASTER_QDSS_BAM, 16, 19, -1, true, NOC_QOS_MODE_FIXED, 1, 1, MSM8998_SLAVE_IMEM, MSM8998_SLAVE_PIMEM, MSM8998_SLAVE_SNOC_CNOC, MSM8998_SLAVE_SNOC_BIMC);
|
||||
DEFINE_QNODE(mas_snoc_cfg, MSM8998_MASTER_SNOC_CFG, 16, 20, -1, false, -1, 0, -1, MSM8998_SLAVE_SRVC_SNOC);
|
||||
DEFINE_QNODE(mas_bimc_snoc_0, MSM8998_MASTER_BIMC_SNOC_0, 16, 21, -1, false, -1, 0, -1, MSM8998_SLAVE_PIMEM, MSM8998_SLAVE_LPASS, MSM8998_SLAVE_HMSS, MSM8998_SLAVE_WLAN, MSM8998_SLAVE_SNOC_CNOC, MSM8998_SLAVE_IMEM, MSM8998_SLAVE_QDSS_STM);
|
||||
DEFINE_QNODE(mas_bimc_snoc_1, MSM8998_MASTER_BIMC_SNOC_1, 16, 109, -1, true, -1, 0, -1, MSM8998_SLAVE_PCIE_0);
|
||||
DEFINE_QNODE(mas_a1noc_snoc, MSM8998_MASTER_A1NOC_SNOC, 16, 111, -1, false, -1, 0, -1, MSM8998_SLAVE_PIMEM, MSM8998_SLAVE_PCIE_0, MSM8998_SLAVE_LPASS, MSM8998_SLAVE_HMSS, MSM8998_SLAVE_SNOC_BIMC, MSM8998_SLAVE_SNOC_CNOC, MSM8998_SLAVE_IMEM, MSM8998_SLAVE_QDSS_STM);
|
||||
DEFINE_QNODE(mas_a2noc_snoc, MSM8998_MASTER_A2NOC_SNOC, 16, 112, -1, false, -1, 0, -1, MSM8998_SLAVE_PIMEM, MSM8998_SLAVE_PCIE_0, MSM8998_SLAVE_LPASS, MSM8998_SLAVE_HMSS, MSM8998_SLAVE_SNOC_BIMC, MSM8998_SLAVE_WLAN, MSM8998_SLAVE_SNOC_CNOC, MSM8998_SLAVE_IMEM, MSM8998_SLAVE_QDSS_STM);
|
||||
DEFINE_QNODE(mas_qdss_etr, MSM8998_MASTER_QDSS_ETR, 16, 31, -1, true, NOC_QOS_MODE_FIXED, 1, 2, MSM8998_SLAVE_IMEM, MSM8998_MASTER_PIMEM, MSM8998_SLAVE_SNOC_CNOC, MSM8998_SLAVE_SNOC_BIMC);
|
||||
|
||||
/* slaves */
|
||||
DEFINE_QNODE(slv_a1noc_snoc, MSM8998_SLAVE_A1NOC_SNOC, 16, -1, 142, false, -1, 0, -1, MSM8998_MASTER_A1NOC_SNOC);
|
||||
DEFINE_QNODE(slv_a2noc_snoc, MSM8998_SLAVE_A2NOC_SNOC, 16, -1, 143, false, -1, 0, -1, MSM8998_MASTER_A2NOC_SNOC);
|
||||
DEFINE_QNODE(slv_ebi, MSM8998_SLAVE_EBI, 8, -1, 0, false, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_hmss_l3, MSM8998_SLAVE_HMSS_L3, 8, -1, 160, false, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_bimc_snoc_0, MSM8998_SLAVE_BIMC_SNOC_0, 8, -1, 2, false, -1, 0, -1, MSM8998_MASTER_BIMC_SNOC_0);
|
||||
DEFINE_QNODE(slv_bimc_snoc_1, MSM8998_SLAVE_BIMC_SNOC_1, 8, -1, 138, true, -1, 0, -1, MSM8998_MASTER_BIMC_SNOC_1);
|
||||
DEFINE_QNODE(slv_cnoc_a2noc, MSM8998_SLAVE_CNOC_A2NOC, 4, -1, 208, true, -1, 0, -1, MSM8998_MASTER_CNOC_A2NOC);
|
||||
DEFINE_QNODE(slv_ssc_cfg, MSM8998_SLAVE_SSC_CFG, 4, -1, 177, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_mpm, MSM8998_SLAVE_MPM, 4, -1, 62, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_pmic_arb, MSM8998_SLAVE_PMIC_ARB, 4, -1, 59, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_tlmm_north, MSM8998_SLAVE_TLMM_NORTH, 4, -1, 214, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_pimem_cfg, MSM8998_SLAVE_PIMEM_CFG, 4, -1, 167, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_imem_cfg, MSM8998_SLAVE_IMEM_CFG, 4, -1, 54, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_message_ram, MSM8998_SLAVE_MESSAGE_RAM, 4, -1, 55, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_skl, MSM8998_SLAVE_SKL, 4, -1, 196, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_bimc_cfg, MSM8998_SLAVE_BIMC_CFG, 4, -1, 56, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_prng, MSM8998_SLAVE_PRNG, 4, -1, 44, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_a2noc_cfg, MSM8998_SLAVE_A2NOC_CFG, 4, -1, 150, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_ipa, MSM8998_SLAVE_IPA, 4, -1, 183, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_tcsr, MSM8998_SLAVE_TCSR, 4, -1, 50, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_snoc_cfg, MSM8998_SLAVE_SNOC_CFG, 4, -1, 70, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_clk_ctl, MSM8998_SLAVE_CLK_CTL, 4, -1, 47, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_glm, MSM8998_SLAVE_GLM, 4, -1, 209, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_spdm, MSM8998_SLAVE_SPDM, 4, -1, 60, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_gpuss_cfg, MSM8998_SLAVE_GPUSS_CFG, 4, -1, 11, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_cnoc_mnoc_cfg, MSM8998_SLAVE_CNOC_MNOC_CFG, 4, -1, 66, true, -1, 0, -1, MSM8998_MASTER_CNOC_MNOC_CFG);
|
||||
DEFINE_QNODE(slv_qm_cfg, MSM8998_SLAVE_QM_CFG, 4, -1, 212, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_mss_cfg, MSM8998_SLAVE_MSS_CFG, 4, -1, 48, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_ufs_cfg, MSM8998_SLAVE_UFS_CFG, 4, -1, 92, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_tlmm_west, MSM8998_SLAVE_TLMM_WEST, 4, -1, 215, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_a1noc_cfg, MSM8998_SLAVE_A1NOC_CFG, 4, -1, 147, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_ahb2phy, MSM8998_SLAVE_AHB2PHY, 4, -1, 163, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_blsp_2, MSM8998_SLAVE_BLSP_2, 4, -1, 37, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_pdm, MSM8998_SLAVE_PDM, 4, -1, 41, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_usb3_0, MSM8998_SLAVE_USB3_0, 4, -1, 22, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_a1noc_smmu_cfg, MSM8998_SLAVE_A1NOC_SMMU_CFG, 8, -1, 149, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_blsp_1, MSM8998_SLAVE_BLSP_1, 4, -1, 39, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_sdcc_2, MSM8998_SLAVE_SDCC_2, 4, -1, 33, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_sdcc_4, MSM8998_SLAVE_SDCC_4, 4, -1, 34, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_tsif, MSM8998_SLAVE_TSIF, 4, -1, 35, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_qdss_cfg, MSM8998_SLAVE_QDSS_CFG, 4, -1, 63, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_tlmm_east, MSM8998_SLAVE_TLMM_EAST, 4, -1, 213, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_cnoc_mnoc_mmss_cfg, MSM8998_SLAVE_CNOC_MNOC_MMSS_CFG, 8, -1, 58, true, -1, 0, -1, MSM8998_MASTER_CNOC_MNOC_MMSS_CFG);
|
||||
DEFINE_QNODE(slv_srvc_cnoc, MSM8998_SLAVE_SRVC_CNOC, 4, -1, 76, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_crvirt_a2noc, MSM8998_SLAVE_CRVIRT_A2NOC, 8, -1, 207, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_gnoc_bimc, MSM8998_SLAVE_GNOC_BIMC, 32, -1, 210, true, -1, 0, -1, MSM8998_MASTER_GNOC_BIMC);
|
||||
DEFINE_QNODE(slv_camera_cfg, MSM8998_SLAVE_CAMERA_CFG, 8, -1, 3, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_camera_throttle_cfg, MSM8998_SLAVE_CAMERA_THROTTLE_CFG, 8, -1, 154, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_misc_cfg, MSM8998_SLAVE_MISC_CFG, 8, -1, 8, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_venus_throttle_cfg, MSM8998_SLAVE_VENUS_THROTTLE_CFG, 8, -1, 178, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_venus_cfg, MSM8998_SLAVE_VENUS_CFG, 8, -1, 10, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_vmem_cfg, MSM8998_SLAVE_VMEM_CFG, 8, -1, 180, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_mmss_clk_xpu_cfg, MSM8998_SLAVE_MMSS_CLK_XPU_CFG, 8, -1, 13, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_mmss_clk_cfg, MSM8998_SLAVE_MMSS_CLK_CFG, 8, -1, 12, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_display_cfg, MSM8998_SLAVE_DISPLAY_CFG, 8, -1, 4, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_display_throttle_cfg, MSM8998_SLAVE_DISPLAY_THROTTLE_CFG, 4, -1, 156, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_smmu_cfg, MSM8998_SLAVE_SMMU_CFG, 8, -1, 205, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_mnoc_bimc, MSM8998_SLAVE_MNOC_BIMC, 32, -1, 16, true, -1, 0, -1, MSM8998_MASTER_MNOC_BIMC);
|
||||
DEFINE_QNODE(slv_vmem, MSM8998_SLAVE_VMEM, 32, -1, 179, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_srvc_mnoc, MSM8998_SLAVE_SRVC_MNOC, 8, -1, 17, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_hmss, MSM8998_SLAVE_HMSS, 16, -1, 20, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_lpass, MSM8998_SLAVE_LPASS, 16, -1, 21, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_wlan, MSM8998_SLAVE_WLAN, 16, -1, 206, false, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_snoc_bimc, MSM8998_SLAVE_SNOC_BIMC, 32, -1, 24, false, -1, 0, -1, MSM8998_MASTER_SNOC_BIMC);
|
||||
DEFINE_QNODE(slv_snoc_cnoc, MSM8998_SLAVE_SNOC_CNOC, 16, -1, 25, false, -1, 0, -1, MSM8998_MASTER_SNOC_CNOC);
|
||||
DEFINE_QNODE(slv_imem, MSM8998_SLAVE_IMEM, 16, -1, 26, false, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_pimem, MSM8998_SLAVE_PIMEM, 16, -1, 166, false, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_qdss_stm, MSM8998_SLAVE_QDSS_STM, 16, -1, 30, false, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_pcie_0, MSM8998_SLAVE_PCIE_0, 16, -1, 84, true, -1, 0, -1, 0);
|
||||
DEFINE_QNODE(slv_srvc_snoc, MSM8998_SLAVE_SRVC_SNOC, 16, -1, 29, false, -1, 0, -1, 0);
|
||||
|
||||
static struct qcom_icc_node *msm8998_a1noc_nodes[] = {
|
||||
[MASTER_PCIE_0] = &mas_pcie_0,
|
||||
[MASTER_USB3] = &mas_usb3,
|
||||
[MASTER_UFS] = &mas_ufs,
|
||||
[MASTER_BLSP_2] = &mas_blsp_2,
|
||||
[SLAVE_A1NOC_SNOC] = &slv_a1noc_snoc,
|
||||
};
|
||||
|
||||
static const struct regmap_config msm8998_a1noc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x60000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct qcom_icc_desc msm8998_a1noc = {
|
||||
.nodes = msm8998_a1noc_nodes,
|
||||
.num_nodes = ARRAY_SIZE(msm8998_a1noc_nodes),
|
||||
.regmap_cfg = &msm8998_a1noc_regmap_config,
|
||||
};
|
||||
|
||||
static struct qcom_icc_node *msm8998_a2noc_nodes[] = {
|
||||
[MASTER_IPA] = &mas_ipa,
|
||||
[MASTER_CNOC_A2NOC] = &mas_cnoc_a2noc,
|
||||
[MASTER_SDCC_2] = &mas_sdcc_2,
|
||||
[MASTER_SDCC_4] = &mas_sdcc_4,
|
||||
[MASTER_TSIF] = &mas_tsif,
|
||||
[MASTER_BLSP_1] = &mas_blsp_1,
|
||||
[MASTER_CRVIRT_A2NOC] = &mas_crvirt_a2noc,
|
||||
[MASTER_CRYPTO_C0] = &mas_crypto,
|
||||
[SLAVE_A2NOC_SNOC] = &slv_a2noc_snoc,
|
||||
[SLAVE_CRVIRT_A2NOC] = &slv_crvirt_a2noc,
|
||||
};
|
||||
|
||||
static const struct regmap_config msm8998_a2noc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x60000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct qcom_icc_desc msm8998_a2noc = {
|
||||
.nodes = msm8998_a2noc_nodes,
|
||||
.num_nodes = ARRAY_SIZE(msm8998_a2noc_nodes),
|
||||
.regmap_cfg = &msm8998_a2noc_regmap_config,
|
||||
};
|
||||
|
||||
static struct qcom_icc_node *msm8998_bimc_nodes[] = {
|
||||
[MASTER_GNOC_BIMC] = &mas_gnoc_bimc,
|
||||
[MASTER_OXILI] = &mas_oxili,
|
||||
[MASTER_MNOC_BIMC] = &mas_mnoc_bimc,
|
||||
[MASTER_SNOC_BIMC] = &mas_snoc_bimc,
|
||||
[SLAVE_EBI] = &slv_ebi,
|
||||
[SLAVE_HMSS_L3] = &slv_hmss_l3,
|
||||
[SLAVE_BIMC_SNOC_0] = &slv_bimc_snoc_0,
|
||||
[SLAVE_BIMC_SNOC_1] = &slv_bimc_snoc_1,
|
||||
};
|
||||
|
||||
static const struct regmap_config msm8998_bimc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x80000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct qcom_icc_desc msm8998_bimc = {
|
||||
.nodes = msm8998_bimc_nodes,
|
||||
.num_nodes = ARRAY_SIZE(msm8998_bimc_nodes),
|
||||
.regmap_cfg = &msm8998_bimc_regmap_config,
|
||||
};
|
||||
|
||||
static struct qcom_icc_node *msm8998_cnoc_nodes[] = {
|
||||
[MASTER_SNOC_CNOC] = &mas_snoc_cnoc,
|
||||
[MASTER_QDSS_DAP] = &mas_qdss_dap,
|
||||
[SLAVE_CNOC_A2NOC] = &slv_cnoc_a2noc,
|
||||
[SLAVE_SSC_CFG] = &slv_ssc_cfg,
|
||||
[SLAVE_MPM] = &slv_mpm,
|
||||
[SLAVE_PMIC_ARB] = &slv_pmic_arb,
|
||||
[SLAVE_TLMM_NORTH] = &slv_tlmm_north,
|
||||
[SLAVE_PIMEM_CFG] = &slv_pimem_cfg,
|
||||
[SLAVE_IMEM_CFG] = &slv_imem_cfg,
|
||||
[SLAVE_MESSAGE_RAM] = &slv_message_ram,
|
||||
[SLAVE_SKL] = &slv_skl,
|
||||
[SLAVE_BIMC_CFG] = &slv_bimc_cfg,
|
||||
[SLAVE_PRNG] = &slv_prng,
|
||||
[SLAVE_A2NOC_CFG] = &slv_a2noc_cfg,
|
||||
[SLAVE_IPA] = &slv_ipa,
|
||||
[SLAVE_TCSR] = &slv_tcsr,
|
||||
[SLAVE_SNOC_CFG] = &slv_snoc_cfg,
|
||||
[SLAVE_CLK_CTL] = &slv_clk_ctl,
|
||||
[SLAVE_GLM] = &slv_glm,
|
||||
[SLAVE_SPDM] = &slv_spdm,
|
||||
[SLAVE_GPUSS_CFG] = &slv_gpuss_cfg,
|
||||
[SLAVE_CNOC_MNOC_CFG] = &slv_cnoc_mnoc_cfg,
|
||||
[SLAVE_QM_CFG] = &slv_qm_cfg,
|
||||
[SLAVE_MSS_CFG] = &slv_mss_cfg,
|
||||
[SLAVE_UFS_CFG] = &slv_ufs_cfg,
|
||||
[SLAVE_TLMM_WEST] = &slv_tlmm_west,
|
||||
[SLAVE_A1NOC_CFG] = &slv_a1noc_cfg,
|
||||
[SLAVE_AHB2PHY] = &slv_ahb2phy,
|
||||
[SLAVE_BLSP_2] = &slv_blsp_2,
|
||||
[SLAVE_PDM] = &slv_pdm,
|
||||
[SLAVE_USB3_0] = &slv_usb3_0,
|
||||
[SLAVE_A1NOC_SMMU_CFG] = &slv_a1noc_smmu_cfg,
|
||||
[SLAVE_BLSP_1] = &slv_blsp_1,
|
||||
[SLAVE_SDCC_2] = &slv_sdcc_2,
|
||||
[SLAVE_SDCC_4] = &slv_sdcc_4,
|
||||
[SLAVE_TSIF] = &slv_tsif,
|
||||
[SLAVE_QDSS_CFG] = &slv_qdss_cfg,
|
||||
[SLAVE_TLMM_EAST] = &slv_tlmm_east,
|
||||
[SLAVE_CNOC_MNOC_MMSS_CFG] = &slv_cnoc_mnoc_mmss_cfg,
|
||||
[SLAVE_SRVC_CNOC] = &slv_srvc_cnoc,
|
||||
};
|
||||
|
||||
static const struct regmap_config msm8998_cnoc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x10000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct qcom_icc_desc msm8998_cnoc = {
|
||||
.nodes = msm8998_cnoc_nodes,
|
||||
.num_nodes = ARRAY_SIZE(msm8998_cnoc_nodes),
|
||||
.regmap_cfg = &msm8998_cnoc_regmap_config,
|
||||
};
|
||||
|
||||
static struct qcom_icc_node *msm8998_gnoc_nodes[] = {
|
||||
[MASTER_APSS_PROC] = &mas_apss_proc,
|
||||
[SLAVE_GNOC_BIMC] = &slv_gnoc_bimc,
|
||||
};
|
||||
|
||||
static const struct regmap_config msm8998_gnoc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x10000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct qcom_icc_desc msm8998_gnoc = {
|
||||
.nodes = msm8998_gnoc_nodes,
|
||||
.num_nodes = ARRAY_SIZE(msm8998_gnoc_nodes),
|
||||
.regmap_cfg = &msm8998_gnoc_regmap_config,
|
||||
};
|
||||
|
||||
static struct qcom_icc_node *msm8998_mnoc_nodes[] = {
|
||||
[MASTER_CNOC_MNOC_CFG] = &mas_cnoc_mnoc_cfg,
|
||||
[MASTER_CPP] = &mas_cpp,
|
||||
[MASTER_JPEG] = &mas_jpeg,
|
||||
[MASTER_MDP_P0] = &mas_mdp_p0,
|
||||
[MASTER_MDP_P1] = &mas_mdp_p1,
|
||||
[MASTER_ROTATOR] = &mas_rotator,
|
||||
[MASTER_VENUS] = &mas_venus,
|
||||
[MASTER_VFE] = &mas_vfe,
|
||||
[MASTER_VENUS_VMEM] = &mas_venus_vmem,
|
||||
[SLAVE_MNOC_BIMC] = &slv_mnoc_bimc,
|
||||
[SLAVE_VMEM] = &slv_vmem,
|
||||
[SLAVE_SRVC_MNOC] = &slv_srvc_mnoc,
|
||||
[MASTER_CNOC_MNOC_MMSS_CFG] = &mas_cnoc_mnoc_mmss_cfg,
|
||||
[SLAVE_CAMERA_CFG] = &slv_camera_cfg,
|
||||
[SLAVE_CAMERA_THROTTLE_CFG] = &slv_camera_throttle_cfg,
|
||||
[SLAVE_MISC_CFG] = &slv_misc_cfg,
|
||||
[SLAVE_VENUS_THROTTLE_CFG] = &slv_venus_throttle_cfg,
|
||||
[SLAVE_VENUS_CFG] = &slv_venus_cfg,
|
||||
[SLAVE_VMEM_CFG] = &slv_vmem_cfg,
|
||||
[SLAVE_MMSS_CLK_XPU_CFG] = &slv_mmss_clk_xpu_cfg,
|
||||
[SLAVE_MMSS_CLK_CFG] = &slv_mmss_clk_cfg,
|
||||
[SLAVE_DISPLAY_CFG] = &slv_display_cfg,
|
||||
[SLAVE_DISPLAY_THROTTLE_CFG] = &slv_display_throttle_cfg,
|
||||
[SLAVE_SMMU_CFG] = &slv_smmu_cfg,
|
||||
};
|
||||
|
||||
static const struct regmap_config msm8998_mnoc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x10000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct qcom_icc_desc msm8998_mnoc = {
|
||||
.nodes = msm8998_mnoc_nodes,
|
||||
.num_nodes = ARRAY_SIZE(msm8998_mnoc_nodes),
|
||||
.regmap_cfg = &msm8998_mnoc_regmap_config,
|
||||
};
|
||||
|
||||
static struct qcom_icc_node *msm8998_snoc_nodes[] = {
|
||||
[MASTER_HMSS] = &mas_hmss,
|
||||
[MASTER_QDSS_BAM] = &mas_qdss_bam,
|
||||
[MASTER_SNOC_CFG] = &mas_snoc_cfg,
|
||||
[MASTER_BIMC_SNOC_0] = &mas_bimc_snoc_0,
|
||||
[MASTER_BIMC_SNOC_1] = &mas_bimc_snoc_1,
|
||||
[MASTER_A1NOC_SNOC] = &mas_a1noc_snoc,
|
||||
[MASTER_A2NOC_SNOC] = &mas_a2noc_snoc,
|
||||
[MASTER_QDSS_ETR] = &mas_qdss_etr,
|
||||
[SLAVE_HMSS] = &slv_hmss,
|
||||
[SLAVE_LPASS] = &slv_lpass,
|
||||
[SLAVE_WLAN] = &slv_wlan,
|
||||
[SLAVE_SNOC_BIMC] = &slv_snoc_bimc,
|
||||
[SLAVE_SNOC_CNOC] = &slv_snoc_cnoc,
|
||||
[SLAVE_IMEM] = &slv_imem,
|
||||
[SLAVE_PIMEM] = &slv_pimem,
|
||||
[SLAVE_QDSS_STM] = &slv_qdss_stm,
|
||||
[SLAVE_PCIE_0] = &slv_pcie_0,
|
||||
[SLAVE_SRVC_SNOC] = &slv_srvc_snoc,
|
||||
};
|
||||
|
||||
static const struct regmap_config msm8998_snoc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x40000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct qcom_icc_desc msm8998_snoc = {
|
||||
.nodes = msm8998_snoc_nodes,
|
||||
.num_nodes = ARRAY_SIZE(msm8998_snoc_nodes),
|
||||
.regmap_cfg = &msm8998_snoc_regmap_config,
|
||||
};
|
||||
|
||||
static int qcom_icc_bimc_set_qos_health(struct regmap *rmap,
|
||||
struct qcom_icc_qos *qos,
|
||||
int regnum)
|
||||
{
|
||||
u32 val;
|
||||
u32 mask;
|
||||
|
||||
val = qos->prio_level;
|
||||
mask = M_BKE_HEALTH_CFG_PRIOLVL_MASK;
|
||||
|
||||
val |= qos->areq_prio << M_BKE_HEALTH_CFG_AREQPRIO_SHIFT;
|
||||
mask |= M_BKE_HEALTH_CFG_AREQPRIO_MASK;
|
||||
|
||||
/* LIMITCMDS is not present on M_BKE_HEALTH_3 */
|
||||
if (regnum != 3) {
|
||||
val |= qos->limit_commands << M_BKE_HEALTH_CFG_LIMITCMDS_SHIFT;
|
||||
mask |= M_BKE_HEALTH_CFG_LIMITCMDS_MASK;
|
||||
}
|
||||
|
||||
return regmap_update_bits(rmap,
|
||||
M_BKE_HEALTH_CFG_ADDR(regnum, qos->qos_port),
|
||||
mask, val);
|
||||
}
|
||||
|
||||
static int qcom_icc_set_bimc_qos(struct icc_node *src, u64 max_bw,
|
||||
bool bypass_mode)
|
||||
{
|
||||
struct qcom_icc_provider *qp;
|
||||
struct qcom_icc_node *qn;
|
||||
struct icc_provider *provider;
|
||||
u32 mode = NOC_QOS_MODE_BYPASS;
|
||||
u32 val = 0;
|
||||
int i, rc = 0;
|
||||
|
||||
qn = src->data;
|
||||
provider = src->provider;
|
||||
qp = to_qcom_provider(provider);
|
||||
|
||||
if (qn->qos.qos_mode != -1)
|
||||
mode = qn->qos.qos_mode;
|
||||
|
||||
/*
|
||||
* QoS Priority: The QoS Health parameters are getting considered
|
||||
* only if we are NOT in Bypass Mode.
|
||||
*/
|
||||
if (mode != NOC_QOS_MODE_BYPASS) {
|
||||
for (i = 3; i >= 0; i--) {
|
||||
rc = qcom_icc_bimc_set_qos_health(qp->regmap,
|
||||
&qn->qos, i);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Set BKE_EN to 1 when Fixed, Regulator or Limiter Mode */
|
||||
val = 1;
|
||||
}
|
||||
|
||||
return regmap_update_bits(qp->regmap, M_BKE_EN_ADDR(qn->qos.qos_port),
|
||||
M_BKE_EN_EN_BMASK, val);
|
||||
}
|
||||
|
||||
static int qcom_icc_noc_set_qos_priority(struct regmap *rmap,
|
||||
struct qcom_icc_qos *qos)
|
||||
{
|
||||
u32 val;
|
||||
int rc;
|
||||
|
||||
/* Must be updated one at a time, P1 first, P0 last */
|
||||
val = qos->areq_prio << NOC_QOS_PRIORITY_P1_SHIFT;
|
||||
rc = regmap_update_bits(rmap, NOC_QOS_PRIORITYn_ADDR(qos->qos_port),
|
||||
NOC_QOS_PRIORITY_MASK, val);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
val = qos->prio_level << NOC_QOS_PRIORITY_P0_SHIFT;
|
||||
return regmap_update_bits(rmap, NOC_QOS_PRIORITYn_ADDR(qos->qos_port),
|
||||
NOC_QOS_PRIORITY_MASK, val);
|
||||
}
|
||||
|
||||
static int qcom_icc_set_noc_qos(struct icc_node *src, u64 max_bw)
|
||||
{
|
||||
struct qcom_icc_provider *qp;
|
||||
struct qcom_icc_node *qn;
|
||||
struct icc_provider *provider;
|
||||
u32 mode = NOC_QOS_MODE_BYPASS;
|
||||
int rc = 0;
|
||||
|
||||
qn = src->data;
|
||||
provider = src->provider;
|
||||
qp = to_qcom_provider(provider);
|
||||
|
||||
if (qn->qos.qos_port < 0) {
|
||||
dev_dbg(src->provider->dev,
|
||||
"NoC QoS: Skipping %s: vote aggregated on parent.\n",
|
||||
qn->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (qn->qos.qos_mode != -1)
|
||||
mode = qn->qos.qos_mode;
|
||||
|
||||
if (mode == NOC_QOS_MODE_FIXED) {
|
||||
dev_dbg(src->provider->dev, "NoC QoS: %s: Set Fixed mode\n",
|
||||
qn->name);
|
||||
rc = qcom_icc_noc_set_qos_priority(qp->regmap, &qn->qos);
|
||||
if (rc)
|
||||
return rc;
|
||||
} else if (mode == NOC_QOS_MODE_BYPASS) {
|
||||
dev_dbg(src->provider->dev, "NoC QoS: %s: Set Bypass mode\n",
|
||||
qn->name);
|
||||
}
|
||||
|
||||
return regmap_update_bits(qp->regmap,
|
||||
NOC_QOS_MODEn_ADDR(qn->qos.qos_port),
|
||||
NOC_QOS_MODEn_MASK, mode);
|
||||
}
|
||||
|
||||
static int qcom_icc_qos_set(struct icc_node *node, u64 sum_bw)
|
||||
{
|
||||
struct qcom_icc_provider *qp = to_qcom_provider(node->provider);
|
||||
struct qcom_icc_node *qn = node->data;
|
||||
|
||||
dev_dbg(node->provider->dev, "Setting QoS for %s\n", qn->name);
|
||||
|
||||
if (qp->is_bimc_node)
|
||||
return qcom_icc_set_bimc_qos(node, sum_bw,
|
||||
(qn->qos.qos_mode == NOC_QOS_MODE_BYPASS));
|
||||
|
||||
return qcom_icc_set_noc_qos(node, sum_bw);
|
||||
}
|
||||
|
||||
static int qcom_icc_rpm_set(int mas_rpm_id, int slv_rpm_id, u64 sum_bw)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (mas_rpm_id != -1) {
|
||||
ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE,
|
||||
RPM_BUS_MASTER_REQ,
|
||||
mas_rpm_id,
|
||||
sum_bw);
|
||||
if (ret) {
|
||||
pr_err("qcom_icc_rpm_smd_send mas %d error %d\n",
|
||||
mas_rpm_id, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (slv_rpm_id != -1) {
|
||||
ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE,
|
||||
RPM_BUS_SLAVE_REQ,
|
||||
slv_rpm_id,
|
||||
sum_bw);
|
||||
if (ret) {
|
||||
pr_err("qcom_icc_rpm_smd_send slv %d error %d\n",
|
||||
slv_rpm_id, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qcom_icc_set(struct icc_node *src, struct icc_node *dst)
|
||||
{
|
||||
struct qcom_icc_provider *qp;
|
||||
struct qcom_icc_node *qn;
|
||||
struct icc_provider *provider;
|
||||
struct icc_node *n;
|
||||
u64 sum_bw;
|
||||
u64 max_peak_bw;
|
||||
u64 rate;
|
||||
u32 agg_avg = 0;
|
||||
u32 agg_peak = 0;
|
||||
int ret, i;
|
||||
|
||||
qn = src->data;
|
||||
provider = src->provider;
|
||||
qp = to_qcom_provider(provider);
|
||||
|
||||
list_for_each_entry(n, &provider->nodes, node_list)
|
||||
provider->aggregate(n, 0, n->avg_bw, n->peak_bw,
|
||||
&agg_avg, &agg_peak);
|
||||
|
||||
sum_bw = icc_units_to_bps(agg_avg);
|
||||
max_peak_bw = icc_units_to_bps(agg_peak);
|
||||
|
||||
if (!qn->qos.ap_owned) {
|
||||
/* send bandwidth request message to the RPM processor */
|
||||
ret = qcom_icc_rpm_set(qn->mas_rpm_id, qn->slv_rpm_id, sum_bw);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else if (qn->qos.qos_mode != -1) {
|
||||
/* set bandwidth directly from the AP */
|
||||
ret = qcom_icc_qos_set(src, sum_bw);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
rate = max(sum_bw, max_peak_bw);
|
||||
|
||||
do_div(rate, qn->buswidth);
|
||||
|
||||
if (qn->rate == rate)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < qp->num_clks; i++) {
|
||||
ret = clk_set_rate(qp->bus_clks[i].clk, rate);
|
||||
if (ret) {
|
||||
pr_err("%s clk_set_rate error: %d\n",
|
||||
qp->bus_clks[i].id, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
qn->rate = rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qnoc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct qcom_icc_desc *desc;
|
||||
struct icc_onecell_data *data;
|
||||
struct icc_provider *provider;
|
||||
struct qcom_icc_node **qnodes;
|
||||
struct qcom_icc_provider *qp;
|
||||
struct icc_node *node;
|
||||
struct resource *res;
|
||||
size_t num_nodes, i;
|
||||
int ret;
|
||||
|
||||
/* wait for the RPM proxy */
|
||||
if (!qcom_icc_rpm_smd_available())
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
desc = of_device_get_match_data(dev);
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
qnodes = desc->nodes;
|
||||
num_nodes = desc->num_nodes;
|
||||
|
||||
qp = devm_kzalloc(dev, sizeof(*qp), GFP_KERNEL);
|
||||
if (!qp)
|
||||
return -ENOMEM;
|
||||
|
||||
data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes),
|
||||
GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm8998-mnoc")) {
|
||||
qp->bus_clks = devm_kmemdup(dev, bus_mm_clocks,
|
||||
sizeof(bus_mm_clocks), GFP_KERNEL);
|
||||
qp->num_clks = ARRAY_SIZE(bus_mm_clocks);
|
||||
} else {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm8998-bimc"))
|
||||
qp->is_bimc_node = true;
|
||||
|
||||
qp->bus_clks = devm_kmemdup(dev, bus_clocks, sizeof(bus_clocks),
|
||||
GFP_KERNEL);
|
||||
qp->num_clks = ARRAY_SIZE(bus_clocks);
|
||||
}
|
||||
if (!qp->bus_clks)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -ENODEV;
|
||||
|
||||
qp->mmio = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(qp->mmio)) {
|
||||
dev_err(dev, "Cannot ioremap interconnect bus resource\n");
|
||||
return PTR_ERR(qp->mmio);
|
||||
}
|
||||
|
||||
qp->regmap = devm_regmap_init_mmio(dev, qp->mmio, desc->regmap_cfg);
|
||||
if (IS_ERR(qp->regmap)) {
|
||||
dev_err(dev, "Cannot regmap interconnect bus resource\n");
|
||||
return PTR_ERR(qp->regmap);
|
||||
}
|
||||
|
||||
ret = devm_clk_bulk_get(dev, qp->num_clks, qp->bus_clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_bulk_prepare_enable(qp->num_clks, qp->bus_clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
provider = &qp->provider;
|
||||
INIT_LIST_HEAD(&provider->nodes);
|
||||
provider->dev = dev;
|
||||
provider->set = qcom_icc_set;
|
||||
provider->aggregate = icc_std_aggregate;
|
||||
provider->xlate = of_icc_xlate_onecell;
|
||||
provider->data = data;
|
||||
|
||||
ret = icc_provider_add(provider);
|
||||
if (ret) {
|
||||
dev_err(dev, "error adding interconnect provider: %d\n", ret);
|
||||
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_nodes; i++) {
|
||||
size_t j;
|
||||
|
||||
node = icc_node_create(qnodes[i]->id);
|
||||
if (IS_ERR(node)) {
|
||||
ret = PTR_ERR(node);
|
||||
goto err;
|
||||
}
|
||||
|
||||
node->name = qnodes[i]->name;
|
||||
node->data = qnodes[i];
|
||||
icc_node_add(node, provider);
|
||||
|
||||
for (j = 0; j < qnodes[i]->num_links; j++)
|
||||
icc_link_create(node, qnodes[i]->links[j]);
|
||||
|
||||
data->nodes[i] = node;
|
||||
}
|
||||
data->num_nodes = num_nodes;
|
||||
platform_set_drvdata(pdev, qp);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
icc_nodes_remove(provider);
|
||||
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
||||
icc_provider_del(provider);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qnoc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
|
||||
|
||||
icc_nodes_remove(&qp->provider);
|
||||
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
||||
return icc_provider_del(&qp->provider);
|
||||
}
|
||||
|
||||
static const struct of_device_id msm8998_noc_of_match[] = {
|
||||
{ .compatible = "qcom,msm8998-a1noc", .data = &msm8998_a1noc },
|
||||
{ .compatible = "qcom,msm8998-a2noc", .data = &msm8998_a2noc },
|
||||
{ .compatible = "qcom,msm8998-bimc", .data = &msm8998_bimc },
|
||||
{ .compatible = "qcom,msm8998-cnoc", .data = &msm8998_cnoc },
|
||||
{ .compatible = "qcom,msm8998-gnoc", .data = &msm8998_gnoc },
|
||||
{ .compatible = "qcom,msm8998-mnoc", .data = &msm8998_mnoc },
|
||||
{ .compatible = "qcom,msm8998-snoc", .data = &msm8998_snoc },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, msm8998_noc_of_match);
|
||||
|
||||
static struct platform_driver msm8998_noc_driver = {
|
||||
.probe = qnoc_probe,
|
||||
.remove = qnoc_remove,
|
||||
.driver = {
|
||||
.name = "qnoc-msm8998",
|
||||
.of_match_table = msm8998_noc_of_match,
|
||||
.sync_state = icc_sync_state,
|
||||
},
|
||||
};
|
||||
module_platform_driver(msm8998_noc_driver);
|
||||
MODULE_DESCRIPTION("Qualcomm msm8998 NoC driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/adreno-smmu-priv.h>
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
|
||||
|
|
@ -12,6 +13,7 @@
|
|||
|
||||
struct qcom_smmu {
|
||||
struct arm_smmu_device smmu;
|
||||
DECLARE_BITMAP(reset_cb_nodisable_mask, ARM_SMMU_MAX_CBS);
|
||||
bool bypass_quirk;
|
||||
u8 bypass_cbndx;
|
||||
u32 stall_enabled;
|
||||
|
|
@ -180,11 +182,13 @@ static int qcom_adreno_smmu_alloc_context_bank(struct arm_smmu_domain *smmu_doma
|
|||
|
||||
static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
|
||||
{
|
||||
/*
|
||||
const struct device_node *np = smmu->dev->of_node;
|
||||
|
||||
if (of_device_is_compatible(np, "qcom,msm8996-smmu-v2"))
|
||||
if (of_device_is_compatible(np, "qcom,msm8996-smmu-v2") ||
|
||||
of_device_is_compatible(np, "qcom,msm8998-smmu-v2") ||
|
||||
of_device_is_compatible(np, "qcom,sdm630-smmu-v2"))
|
||||
return false;
|
||||
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -228,11 +232,13 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
|
|||
{ .compatible = "qcom,adreno" },
|
||||
{ .compatible = "qcom,mdp4" },
|
||||
{ .compatible = "qcom,mdss" },
|
||||
{ .compatible = "qcom,msm8998-mss-pil" },
|
||||
{ .compatible = "qcom,sc7180-mdss" },
|
||||
{ .compatible = "qcom,sc7180-mss-pil" },
|
||||
{ .compatible = "qcom,sc7280-mdss" },
|
||||
{ .compatible = "qcom,sc7280-mss-pil" },
|
||||
{ .compatible = "qcom,sc8180x-mdss" },
|
||||
{ .compatible = "qcom,sdm660-mss-pil" },
|
||||
{ .compatible = "qcom,sdm845-mdss" },
|
||||
{ .compatible = "qcom,sdm845-mss-pil" },
|
||||
{ }
|
||||
|
|
@ -267,7 +273,8 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
|
|||
reg = arm_smmu_gr0_read(smmu, last_s2cr);
|
||||
if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS) {
|
||||
qsmmu->bypass_quirk = true;
|
||||
qsmmu->bypass_cbndx = smmu->num_context_banks - 1;
|
||||
if (qsmmu->bypass_cbndx == 0xff)
|
||||
qsmmu->bypass_cbndx = smmu->num_context_banks - 1;
|
||||
|
||||
set_bit(qsmmu->bypass_cbndx, smmu->context_map);
|
||||
|
||||
|
|
@ -359,8 +366,15 @@ static int qcom_sdm845_smmu500_reset(struct arm_smmu_device *smmu)
|
|||
static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
|
||||
{
|
||||
const struct device_node *np = smmu->dev->of_node;
|
||||
struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
|
||||
|
||||
arm_mmu500_reset(smmu);
|
||||
/*
|
||||
* Execute the mmu-500 reset implementation detail only if there
|
||||
* are no secured untouchable contexts in this iommu, otherwise
|
||||
* the system will crash.
|
||||
*/
|
||||
if (bitmap_empty(qsmmu->reset_cb_nodisable_mask, ARM_SMMU_MAX_CBS))
|
||||
arm_mmu500_reset(smmu);
|
||||
|
||||
if (of_device_is_compatible(np, "qcom,sdm845-smmu-500"))
|
||||
return qcom_sdm845_smmu500_reset(smmu);
|
||||
|
|
@ -368,11 +382,20 @@ static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool qcom_smmu500_reset_cb_nodisable(struct arm_smmu_device *smmu,
|
||||
int cbndx)
|
||||
{
|
||||
struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
|
||||
|
||||
return test_bit(cbndx, qsmmu->reset_cb_nodisable_mask);
|
||||
}
|
||||
|
||||
static const struct arm_smmu_impl qcom_smmu_impl = {
|
||||
.init_context = qcom_smmu_init_context,
|
||||
.cfg_probe = qcom_smmu_cfg_probe,
|
||||
.def_domain_type = qcom_smmu_def_domain_type,
|
||||
.reset = qcom_smmu500_reset,
|
||||
.reset_cb_nodisable = qcom_smmu500_reset_cb_nodisable,
|
||||
.write_s2cr = qcom_smmu_write_s2cr,
|
||||
};
|
||||
|
||||
|
|
@ -380,6 +403,7 @@ static const struct arm_smmu_impl qcom_adreno_smmu_impl = {
|
|||
.init_context = qcom_adreno_smmu_init_context,
|
||||
.def_domain_type = qcom_smmu_def_domain_type,
|
||||
.reset = qcom_smmu500_reset,
|
||||
.reset_cb_nodisable = qcom_smmu500_reset_cb_nodisable,
|
||||
.alloc_context_bank = qcom_adreno_smmu_alloc_context_bank,
|
||||
.write_sctlr = qcom_adreno_smmu_write_sctlr,
|
||||
};
|
||||
|
|
@ -387,7 +411,10 @@ static const struct arm_smmu_impl qcom_adreno_smmu_impl = {
|
|||
static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
|
||||
const struct arm_smmu_impl *impl)
|
||||
{
|
||||
const struct device_node *np = smmu->dev->of_node;
|
||||
struct qcom_smmu *qsmmu;
|
||||
u8 reset_nodisable_cbs[ARM_SMMU_MAX_CBS];
|
||||
int i, sz;
|
||||
|
||||
/* Check to make sure qcom_scm has finished probing */
|
||||
if (!qcom_scm_is_available())
|
||||
|
|
@ -398,6 +425,34 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
|
|||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
qsmmu->smmu.impl = impl;
|
||||
qsmmu->bypass_cbndx = 0xff;
|
||||
bitmap_zero(qsmmu->reset_cb_nodisable_mask, ARM_SMMU_MAX_CBS);
|
||||
|
||||
if (np != NULL) {
|
||||
/*
|
||||
* This property is optional and we expect to fail finding it if:
|
||||
* - Using the default bypass_cbndx (in the .cfg_probe cb) is fine; or
|
||||
* - We are booting on ACPI
|
||||
*/
|
||||
of_property_read_u8(np, "qcom,bypass-cbndx", &qsmmu->bypass_cbndx);
|
||||
|
||||
/*
|
||||
* Some context banks may not be disabled because they are
|
||||
* secured: read from DT a list of secured contexts that cannot
|
||||
* be disabled without crashing the system.
|
||||
* This list is optional, as not all firmware configurations do
|
||||
* require us skipping disablement of context banks.
|
||||
*/
|
||||
sz = of_property_read_variable_u8_array(np, "qcom,reset-nodisable-cbs",
|
||||
reset_nodisable_cbs,
|
||||
1, ARM_SMMU_MAX_CBS);
|
||||
if (sz > 0) {
|
||||
for (i = 0; i < sz; i++) {
|
||||
__set_bit(reset_nodisable_cbs[i],
|
||||
qsmmu->reset_cb_nodisable_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &qsmmu->smmu;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1624,6 +1624,16 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
|
|||
|
||||
/* Make sure all context banks are disabled and clear CB_FSR */
|
||||
for (i = 0; i < smmu->num_context_banks; ++i) {
|
||||
/*
|
||||
* Some context banks cannot be disabled due to hypervisor
|
||||
* configuration on some systems; if this is the case,
|
||||
* skip disabling and writing FAULT on the CB FSR in order
|
||||
* to avoid a system crash.
|
||||
*/
|
||||
if (smmu->impl && smmu->impl->reset_cb_nodisable &&
|
||||
smmu->impl->reset_cb_nodisable(smmu, i)) {
|
||||
continue;
|
||||
}
|
||||
arm_smmu_write_context_bank(smmu, i);
|
||||
arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_FSR, ARM_SMMU_FSR_FAULT);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -429,6 +429,7 @@ struct arm_smmu_impl {
|
|||
u64 val);
|
||||
int (*cfg_probe)(struct arm_smmu_device *smmu);
|
||||
int (*reset)(struct arm_smmu_device *smmu);
|
||||
bool (*reset_cb_nodisable)(struct arm_smmu_device *smmu, int cbndx);
|
||||
int (*init_context)(struct arm_smmu_domain *smmu_domain,
|
||||
struct io_pgtable_cfg *cfg, struct device *dev);
|
||||
void (*tlb_sync)(struct arm_smmu_device *smmu, int page, int sync,
|
||||
|
|
|
|||
|
|
@ -869,6 +869,9 @@ source "drivers/leds/blink/Kconfig"
|
|||
comment "Flash and Torch LED drivers"
|
||||
source "drivers/leds/flash/Kconfig"
|
||||
|
||||
comment "RGB LED drivers"
|
||||
source "drivers/leds/rgb/Kconfig"
|
||||
|
||||
comment "LED Triggers"
|
||||
source "drivers/leds/trigger/Kconfig"
|
||||
|
||||
|
|
|
|||
|
|
@ -99,6 +99,9 @@ obj-$(CONFIG_LEDS_USER) += uleds.o
|
|||
# Flash and Torch LED Drivers
|
||||
obj-$(CONFIG_LEDS_CLASS_FLASH) += flash/
|
||||
|
||||
# RGB LED Drivers
|
||||
obj-$(CONFIG_LEDS_CLASS_MULTICOLOR) += rgb/
|
||||
|
||||
# LED Triggers
|
||||
obj-$(CONFIG_LEDS_TRIGGERS) += trigger/
|
||||
|
||||
|
|
|
|||
18
drivers/leds/rgb/Kconfig
Normal file
18
drivers/leds/rgb/Kconfig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
if LEDS_CLASS_MULTICOLOR
|
||||
|
||||
config LEDS_QCOM_LPG
|
||||
tristate "LED support for Qualcomm LPG"
|
||||
depends on OF
|
||||
depends on SPMI
|
||||
help
|
||||
This option enables support for the Light Pulse Generator found in a
|
||||
wide variety of Qualcomm PMICs. The LPG consists of a number of PWM
|
||||
channels and typically a shared pattern lookup table and a current
|
||||
sink, intended to drive RGB LEDs. Each channel can either be used as
|
||||
a LED, grouped to represent a RGB LED or exposed as PWM channels.
|
||||
|
||||
If compiled as a module, the module will be named leds-qcom-lpg.
|
||||
|
||||
endif # LEDS_CLASS_MULTICOLOR
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue