summaryrefslogtreecommitdiff
path: root/Documentation
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/devicetree/bindings/input/ariel-pwrbutton.yaml57
-rw-r--r--Documentation/devicetree/bindings/input/atmel,maxtouch.txt41
-rw-r--r--Documentation/devicetree/bindings/input/atmel,maxtouch.yaml81
-rw-r--r--Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt33
-rw-r--r--Documentation/devicetree/bindings/input/cypress,tm2-touchkey.yaml73
-rw-r--r--Documentation/devicetree/bindings/input/dlg,da7280.txt108
-rw-r--r--Documentation/devicetree/bindings/input/sprd,sc27xx-vibra.txt23
-rw-r--r--Documentation/devicetree/bindings/input/sprd,sc27xx-vibrator.yaml48
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt2
-rw-r--r--Documentation/driver-api/input.rst9
-rw-r--r--Documentation/input/input-programming.rst46
11 files changed, 414 insertions, 107 deletions
diff --git a/Documentation/devicetree/bindings/input/ariel-pwrbutton.yaml b/Documentation/devicetree/bindings/input/ariel-pwrbutton.yaml
new file mode 100644
index 000000000000..b4ad829d7383
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/ariel-pwrbutton.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/ariel-pwrbutton.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Dell Wyse 3020 a.k.a. "Ariel" Power Button
+
+maintainers:
+ - Lubomir Rintel <lkundrak@v3.sk>
+
+description: |
+ The ENE Embedded Controller on the Ariel board has an interface to the
+ SPI bus that is capable of sending keyboard and mouse data. A single
+ power button is attached to it. This binding describes this
+ configuration.
+
+allOf:
+ - $ref: input.yaml#
+
+properties:
+ compatible:
+ items:
+ - const: dell,wyse-ariel-ec-input
+ - const: ene,kb3930-input
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ spi-max-frequency: true
+
+required:
+ - compatible
+ - reg
+ - interrupts
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ power-button@0 {
+ compatible = "dell,wyse-ariel-ec-input", "ene,kb3930-input";
+ reg = <0>;
+ interrupt-parent = <&gpio>;
+ interrupts = <60 IRQ_TYPE_EDGE_RISING>;
+ spi-max-frequency = <33000000>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
deleted file mode 100644
index c88919480d37..000000000000
--- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-Atmel maXTouch touchscreen/touchpad
-
-Required properties:
-- compatible:
- atmel,maxtouch
-
- The following compatibles have been used in various products but are
- deprecated:
- atmel,qt602240_ts
- atmel,atmel_mxt_ts
- atmel,atmel_mxt_tp
- atmel,mXT224
-
-- reg: The I2C address of the device
-
-- interrupts: The sink for the touchpad's IRQ output
- See ../interrupt-controller/interrupts.txt
-
-Optional properties for main touchpad device:
-
-- linux,gpio-keymap: When enabled, the SPT_GPIOPWN_T19 object sends messages
- on GPIO bit changes. An array of up to 8 entries can be provided
- indicating the Linux keycode mapped to each bit of the status byte,
- starting at the LSB. Linux keycodes are defined in
- <dt-bindings/input/input.h>.
-
- Note: the numbering of the GPIOs and the bit they start at varies between
- maXTouch devices. You must either refer to the documentation, or
- experiment to determine which bit corresponds to which input. Use
- KEY_RESERVED for unused padding values.
-
-- reset-gpios: GPIO specifier for the touchscreen's reset pin (active low)
-
-Example:
-
- touch@4b {
- compatible = "atmel,maxtouch";
- reg = <0x4b>;
- interrupt-parent = <&gpio>;
- interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_LEVEL_LOW>;
- };
diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml b/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml
new file mode 100644
index 000000000000..8c6418f76e94
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/atmel,maxtouch.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel maXTouch touchscreen/touchpad
+
+maintainers:
+ - Nick Dyer <nick@shmanahar.org>
+ - Linus Walleij <linus.walleij@linaro.org>
+
+description: |
+ Atmel maXTouch touchscreen or touchpads such as the mXT244
+ and similar devices.
+
+properties:
+ compatible:
+ const: atmel,maxtouch
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ vdda-supply:
+ description:
+ Optional regulator for the AVDD analog voltage.
+
+ vdd-supply:
+ description:
+ Optional regulator for the VDD digital voltage.
+
+ reset-gpios:
+ maxItems: 1
+ description:
+ Optional GPIO specifier for the touchscreen's reset pin
+ (active low). The line must be flagged with
+ GPIO_ACTIVE_LOW.
+
+ linux,gpio-keymap:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ description: |
+ When enabled, the SPT_GPIOPWN_T19 object sends messages
+ on GPIO bit changes. An array of up to 8 entries can be provided
+ indicating the Linux keycode mapped to each bit of the status byte,
+ starting at the LSB. Linux keycodes are defined in
+ <dt-bindings/input/input.h>.
+
+ Note: the numbering of the GPIOs and the bit they start at varies
+ between maXTouch devices. You must either refer to the documentation,
+ or experiment to determine which bit corresponds to which input. Use
+ KEY_RESERVED for unused padding values.
+
+required:
+ - compatible
+ - reg
+ - interrupts
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/gpio/gpio.h>
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ touchscreen@4a {
+ compatible = "atmel,maxtouch";
+ reg = <0x4a>;
+ interrupt-parent = <&gpio>;
+ interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
+ vdda-supply = <&ab8500_ldo_aux2_reg>;
+ vdd-supply = <&ab8500_ldo_aux5_reg>;
+ };
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt b/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt
deleted file mode 100644
index 921172f689b8..000000000000
--- a/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-Samsung tm2-touchkey
-
-Required properties:
-- compatible:
- * "cypress,tm2-touchkey" - for the touchkey found on the tm2 board
- * "cypress,midas-touchkey" - for the touchkey found on midas boards
- * "cypress,aries-touchkey" - for the touchkey found on aries boards
- * "coreriver,tc360-touchkey" - for the Coreriver TouchCore 360 touchkey
-- reg: I2C address of the chip.
-- interrupts: interrupt to which the chip is connected (see interrupt
- binding[0]).
-- vcc-supply : internal regulator output. 1.8V
-- vdd-supply : power supply for IC 3.3V
-
-Optional properties:
-- linux,keycodes: array of keycodes (max 4), default KEY_PHONE and KEY_BACK
-
-[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
-
-Example:
- &i2c0 {
- /* ... */
-
- touchkey@20 {
- compatible = "cypress,tm2-touchkey";
- reg = <0x20>;
- interrupt-parent = <&gpa3>;
- interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
- vcc-supply=<&ldo32_reg>;
- vdd-supply=<&ldo33_reg>;
- linux,keycodes = <KEY_PHONE KEY_BACK>;
- };
- };
diff --git a/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.yaml b/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.yaml
new file mode 100644
index 000000000000..52dca8b64081
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/cypress,tm2-touchkey.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung TM2 touch key controller
+
+maintainers:
+ - Stephan Gerhold <stephan@gerhold.net>
+
+description: |
+ Touch key controllers similar to the TM2 can be found in a wide range of
+ Samsung devices. They are implemented using many different MCUs, but use
+ a similar I2C protocol.
+
+allOf:
+ - $ref: input.yaml#
+
+properties:
+ compatible:
+ enum:
+ - cypress,tm2-touchkey
+ - cypress,midas-touchkey
+ - cypress,aries-touchkey
+ - coreriver,tc360-touchkey
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ vdd-supply:
+ description: Optional regulator for LED voltage, 3.3V.
+
+ vcc-supply:
+ description: Optional regulator for MCU, 1.8V-3.3V (depending on MCU).
+
+ vddio-supply:
+ description: |
+ Optional regulator that provides digital I/O voltage,
+ e.g. for pulling up the interrupt line or the I2C pins.
+
+ linux,keycodes:
+ minItems: 1
+ maxItems: 4
+
+required:
+ - compatible
+ - reg
+ - interrupts
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/input/input.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ touchkey@20 {
+ compatible = "cypress,tm2-touchkey";
+ reg = <0x20>;
+ interrupt-parent = <&gpa3>;
+ interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+ vcc-supply = <&ldo32_reg>;
+ vdd-supply = <&ldo33_reg>;
+ linux,keycodes = <KEY_MENU KEY_BACK>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/input/dlg,da7280.txt b/Documentation/devicetree/bindings/input/dlg,da7280.txt
new file mode 100644
index 000000000000..96ee5d50e111
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/dlg,da7280.txt
@@ -0,0 +1,108 @@
+Dialog Semiconductor DA7280 Haptics bindings
+
+Required properties:
+- compatible: Should be "dlg,da7280".
+- reg: Specifies the I2C slave address.
+
+- interrupt-parent : Specifies the phandle of the interrupt controller to
+ which the IRQs from DA7280 are delivered to.
+
+- dlg,actuator-type: Set Actuator type. it should be one of:
+ "LRA" - Linear Resonance Actuator type.
+ "ERM-bar" - Bar type Eccentric Rotating Mass.
+ "ERM-coin" - Coin type Eccentric Rotating Mass.
+
+- dlg,const-op-mode: Haptic operation mode for FF_CONSTANT.
+ Possible values:
+ 1 - Direct register override(DRO) mode triggered by i2c(default),
+ 2 - PWM data source mode controlled by PWM duty,
+- dlg,periodic-op-mode: Haptic operation mode for FF_PERIODIC.
+ Possible values:
+ 1 - Register triggered waveform memory(RTWM) mode, the pattern
+ assigned to the PS_SEQ_ID played as much times as PS_SEQ_LOOP,
+ 2 - Edge triggered waveform memory(ETWM) mode, external GPI(N)
+ control are required to enable/disable and it needs to keep
+ device enabled by sending magnitude (X > 0),
+ the pattern is assigned to the GPI(N)_SEQUENCE_ID below.
+ The default value is 1 for both of the operation modes.
+ For more details, please see the datasheet.
+
+- dlg,nom-microvolt: Nominal actuator voltage rating.
+ Valid values: 0 - 6000000.
+- dlg,abs-max-microvolt: Absolute actuator maximum voltage rating.
+ Valid values: 0 - 6000000.
+- dlg,imax-microamp: Actuator max current rating.
+ Valid values: 0 - 252000.
+ Default: 130000.
+- dlg,impd-micro-ohms: the impedance of the actuator in micro ohms.
+ Valid values: 0 - 1500000000.
+
+Optional properties:
+- pwms : phandle to the physical PWM(Pulse Width Modulation) device.
+ PWM properties should be named "pwms". And number of cell is different
+ for each pwm device.
+ (See Documentation/devicetree/bindings/pwm/pwm.txt
+ for further information relating to pwm properties)
+
+- dlg,ps-seq-id: the PS_SEQ_ID(pattern ID in waveform memory inside chip)
+ to play back when RTWM-MODE is enabled.
+ Valid range: 0 - 15.
+- dlg,ps-seq-loop: the PS_SEQ_LOOP, Number of times the pre-stored sequence
+ pointed to by PS_SEQ_ID or GPI(N)_SEQUENCE_ID is repeated.
+ Valid range: 0 - 15.
+- dlg,gpiN-seq-id: the GPI(N)_SEQUENCE_ID, pattern to play
+ when gpi0 is triggered, 'N' must be 0 - 2.
+ Valid range: 0 - 15.
+- dlg,gpiN-mode: the pattern mode which can select either
+ "Single-pattern" or "Multi-pattern", 'N' must be 0 - 2.
+- dlg,gpiN-polarity: gpiN polarity which can be chosen among
+ "Rising-edge", "Falling-edge" and "Both-edge",
+ 'N' must be 0 - 2
+ Haptic will work by this edge option in case of ETWM mode.
+
+- dlg,resonant-freq-hz: use in case of LRA.
+ the frequency range: 50 - 300.
+ Default: 205.
+
+- dlg,bemf-sens-enable: Enable for internal loop computations.
+- dlg,freq-track-enable: Enable for resonant frequency tracking.
+- dlg,acc-enable: Enable for active acceleration.
+- dlg,rapid-stop-enable: Enable for rapid stop.
+- dlg,amp-pid-enable: Enable for the amplitude PID.
+- dlg,mem-array: Customized waveform memory(patterns) data downloaded to
+ the device during initialization. This is an array of 100 values(u8).
+
+For further information, see device datasheet.
+
+======
+
+Example:
+
+ haptics: da7280-haptics@4a {
+ compatible = "dlg,da7280";
+ reg = <0x4a>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+ dlg,actuator-type = "LRA";
+ dlg,dlg,const-op-mode = <1>;
+ dlg,dlg,periodic-op-mode = <1>;
+ dlg,nom-microvolt = <2000000>;
+ dlg,abs-max-microvolt = <2000000>;
+ dlg,imax-microamp = <170000>;
+ dlg,resonant-freq-hz = <180>;
+ dlg,impd-micro-ohms = <10500000>;
+ dlg,freq-track-enable;
+ dlg,rapid-stop-enable;
+ dlg,mem-array = <
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ >;
+ };
diff --git a/Documentation/devicetree/bindings/input/sprd,sc27xx-vibra.txt b/Documentation/devicetree/bindings/input/sprd,sc27xx-vibra.txt
deleted file mode 100644
index f2ec0d4f2dff..000000000000
--- a/Documentation/devicetree/bindings/input/sprd,sc27xx-vibra.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Spreadtrum SC27xx PMIC Vibrator
-
-Required properties:
-- compatible: should be "sprd,sc2731-vibrator".
-- reg: address of vibrator control register.
-
-Example :
-
- sc2731_pmic: pmic@0 {
- compatible = "sprd,sc2731";
- reg = <0>;
- spi-max-frequency = <26000000>;
- interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-controller;
- #interrupt-cells = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- vibrator@eb4 {
- compatible = "sprd,sc2731-vibrator";
- reg = <0xeb4>;
- };
- };
diff --git a/Documentation/devicetree/bindings/input/sprd,sc27xx-vibrator.yaml b/Documentation/devicetree/bindings/input/sprd,sc27xx-vibrator.yaml
new file mode 100644
index 000000000000..5d67fc8ebc18
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/sprd,sc27xx-vibrator.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright 2020 Unisoc Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/sprd,sc27xx-vibrator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Spreadtrum SC27xx PMIC Vibrator Device Tree Bindings
+
+maintainers:
+ - Orson Zhai <orsonzhai@gmail.com>
+ - Baolin Wang <baolin.wang7@gmail.com>
+ - Chunyan Zhang <zhang.lyra@gmail.com>
+
+properties:
+ compatible:
+ enum:
+ - sprd,sc2721-vibrator
+ - sprd,sc2730-vibrator
+ - sprd,sc2731-vibrator
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ sc2731_pmic: pmic@0 {
+ compatible = "sprd,sc2731";
+ reg = <0 0>;
+ spi-max-frequency = <26000000>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vibrator@eb4 {
+ compatible = "sprd,sc2731-vibrator";
+ reg = <0xeb4>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt b/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt
index 94c4fc644940..5eef5e7d6aae 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt
@@ -1,7 +1,7 @@
* Elan eKTF2127 I2C touchscreen controller
Required properties:
- - compatible : "elan,ektf2127"
+ - compatible : "elan,ektf2127" or "elan,ektf2132"
- reg : I2C slave address of the chip (0x40)
- interrupts : interrupt specification for the ektf2127 interrupt
- power-gpios : GPIO specification for the pin connected to the
diff --git a/Documentation/driver-api/input.rst b/Documentation/driver-api/input.rst
index d05bf58fa83e..4bbb26ae2a89 100644
--- a/Documentation/driver-api/input.rst
+++ b/Documentation/driver-api/input.rst
@@ -25,15 +25,6 @@ Multitouch Library
.. kernel-doc:: drivers/input/input-mt.c
:export:
-Polled input devices
---------------------
-
-.. kernel-doc:: include/linux/input-polldev.h
- :internal:
-
-.. kernel-doc:: drivers/input/input-polldev.c
- :export:
-
Matrix keyboards/keypads
------------------------
diff --git a/Documentation/input/input-programming.rst b/Documentation/input/input-programming.rst
index 45a4c6e05e39..5938145b0e35 100644
--- a/Documentation/input/input-programming.rst
+++ b/Documentation/input/input-programming.rst
@@ -164,6 +164,52 @@ disconnects. Calls to both callbacks are serialized.
The open() callback should return a 0 in case of success or any nonzero value
in case of failure. The close() callback (which is void) must always succeed.
+Inhibiting input devices
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Inhibiting a device means ignoring input events from it. As such it is about
+maintaining relationships with input handlers - either already existing
+relationships, or relationships to be established while the device is in
+inhibited state.
+
+If a device is inhibited, no input handler will receive events from it.
+
+The fact that nobody wants events from the device is exploited further, by
+calling device's close() (if there are users) and open() (if there are users) on
+inhibit and uninhibit operations, respectively. Indeed, the meaning of close()
+is to stop providing events to the input core and that of open() is to start
+providing events to the input core.
+
+Calling the device's close() method on inhibit (if there are users) allows the
+driver to save power. Either by directly powering down the device or by
+releasing the runtime-pm reference it got in open() when the driver is using
+runtime-pm.
+
+Inhibiting and uninhibiting are orthogonal to opening and closing the device by
+input handlers. Userspace might want to inhibit a device in anticipation before
+any handler is positively matched against it.
+
+Inhibiting and uninhibiting are orthogonal to device's being a wakeup source,
+too. Being a wakeup source plays a role when the system is sleeping, not when
+the system is operating. How drivers should program their interaction between
+inhibiting, sleeping and being a wakeup source is driver-specific.
+
+Taking the analogy with the network devices - bringing a network interface down
+doesn't mean that it should be impossible be wake the system up on LAN through
+this interface. So, there may be input drivers which should be considered wakeup
+sources even when inhibited. Actually, in many I2C input devices their interrupt
+is declared a wakeup interrupt and its handling happens in driver's core, which
+is not aware of input-specific inhibit (nor should it be). Composite devices
+containing several interfaces can be inhibited on a per-interface basis and e.g.
+inhibiting one interface shouldn't affect the device's capability of being a
+wakeup source.
+
+If a device is to be considered a wakeup source while inhibited, special care
+must be taken when programming its suspend(), as it might need to call device's
+open(). Depending on what close() means for the device in question, not
+opening() it before going to sleep might make it impossible to provide any
+wakeup events. The device is going to sleep anyway.
+
Basic event types
~~~~~~~~~~~~~~~~~